Cleanup 201 and as41 bunch files

This commit is contained in:
Vyacheslav Gerasimov
2021-03-28 16:26:32 +03:00
parent 943f03e55f
commit f2a892a972
135 changed files with 28 additions and 12127 deletions

2
.bunch
View File

@@ -1,4 +1,2 @@
202
201
as41_201
as42

View File

@@ -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
}

View File

@@ -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;
}
}

View File

@@ -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();
}

View File

@@ -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)
}

View File

@@ -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();
}
}

View File

@@ -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>?>

View File

@@ -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>?

View File

@@ -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
}

View File

@@ -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")
}

View File

@@ -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)
}

View File

@@ -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)
}
}

View File

@@ -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;
}
}

View File

@@ -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
)
}
}
}

View File

@@ -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));
}
}

View File

@@ -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>()

View File

@@ -1,19 +0,0 @@
versions.intellijSdk=201.7223.91
versions.idea.NodeJS=193.6494.7
versions.jar.asm-all=7.0.1
versions.jar.guava=28.2-jre
versions.jar.groovy-all=2.4.17
versions.jar.lombok-ast=0.2.3
versions.jar.swingx-core=1.6.2-2
versions.jar.kxml2=2.3.0
versions.jar.streamex=0.7.2
versions.jar.gson=2.8.6
versions.jar.oro=2.0.8
versions.jar.picocontainer=1.2
versions.jar.serviceMessages=2019.1.4
versions.jar.lz4-java=1.7.1
ignore.jar.snappy-in-java=true
versions.gradle-api=4.5.1
versions.shadow=6.1.0
versions.junit-bom=5.7.0
versions.org.junit.platform=1.7.0

View File

@@ -1,23 +0,0 @@
versions.intellijSdk=201.7223.91
versions.idea.NodeJS=193.6494.7
versions.androidStudioRelease=4.1.0.18
versions.androidStudioBuild=201.6823847
versions.jar.asm-all=7.0.1
versions.jar.guava=28.2-jre
versions.jar.groovy-all=2.4.17
versions.jar.lombok-ast=0.2.3
versions.jar.swingx-core=1.6.2-2
versions.jar.kxml2=2.3.0
versions.jar.streamex=0.7.2
versions.jar.gson=2.8.6
versions.jar.oro=2.0.8
versions.jar.picocontainer=1.2
versions.jar.serviceMessages=2019.1.4
versions.jar.lz4-java=1.7.1
ignore.jar.snappy-in-java=true
versions.gradle-api=4.5.1
versions.shadow=6.1.0
ignore.jar.common=true
ignore.jar.lombok-ast=true
versions.junit-bom=5.7.0
versions.org.junit.platform=1.7.0

View File

@@ -1,13 +0,0 @@
import org.jetbrains.annotations.PropertyKey
fun message(@PropertyKey(resourceBundle = "PropertyKeysEmptyString") key: String) = key
fun test() {
message("<caret>")
}
// EXIST: { lookupString: "foo.bar", itemText: "foo.bar", tailText: "1", typeText: "PropertyKeysEmptyString" }
// EXIST: { lookupString: "bar.baz", itemText: "bar.baz", tailText: "2", typeText: "PropertyKeysEmptyString" }
// EXIST: { lookupString: "foo.bar.baz", itemText: "foo.bar.baz", tailText: "3", typeText: "PropertyKeysEmptyString" }
// EXIST: { lookupString: "foo.test", itemText: "foo.test", tailText: "4", typeText: "PropertyKeysEmptyString" }
// NOTHING_ELSE

View File

@@ -1,13 +0,0 @@
import org.jetbrains.annotations.PropertyKey
fun message(@PropertyKey(resourceBundle = "PropertyKeysNoPrefix") key: String) = key
fun test() {
message("<caret>foo")
}
// EXIST: { lookupString: "foo.bar", itemText: "foo.bar", tailText: "1", typeText: "PropertyKeysNoPrefix" }
// EXIST: { lookupString: "bar.baz", itemText: "bar.baz", tailText: "2", typeText: "PropertyKeysNoPrefix" }
// EXIST: { lookupString: "foo.bar.baz", itemText: "foo.bar.baz", tailText: "3", typeText: "PropertyKeysNoPrefix" }
// EXIST: { lookupString: "foo.test", itemText: "foo.test", tailText: "4", typeText: "PropertyKeysNoPrefix" }
// NOTHING_ELSE

View File

@@ -1,12 +0,0 @@
import org.jetbrains.annotations.PropertyKey
fun message(@PropertyKey(resourceBundle = "PropertyKeysWithPrefix") key: String) = key
fun test() {
message("foo.<caret>")
}
// EXIST: { lookupString: "foo.bar", itemText: "foo.bar", tailText: "1", typeText: "PropertyKeysWithPrefix" }
// EXIST: { lookupString: "foo.bar.baz", itemText: "foo.bar.baz", tailText: "3", typeText: "PropertyKeysWithPrefix" }
// EXIST: { lookupString: "foo.test", itemText: "foo.test", tailText: "4", typeText: "PropertyKeysWithPrefix" }
// NOTHING_ELSE

View File

@@ -1,43 +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.idea
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
import com.intellij.openapi.Disposable
import com.intellij.openapi.fileEditor.FileEditor
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.util.application.getServiceSafe
class DaemonCodeAnalyzerStatusService(project: Project) : Disposable {
companion object {
fun getInstance(project: Project): DaemonCodeAnalyzerStatusService = project.getServiceSafe()
}
@Volatile
var daemonRunning: Boolean = false
private set
init {
val messageBusConnection = project.messageBus.connect(this)
messageBusConnection.subscribe(DaemonCodeAnalyzer.DAEMON_EVENT_TOPIC, object : DaemonCodeAnalyzer.DaemonListener {
override fun daemonStarting(fileEditors: MutableCollection<FileEditor>) {
daemonRunning = true
}
override fun daemonFinished(fileEditors: MutableCollection<FileEditor>) {
daemonRunning = false
}
override fun daemonCancelEventOccurred(reason: String) {
daemonRunning = false
}
})
}
override fun dispose() {
}
}

View File

@@ -1,18 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.idea.statistics
open class KotlinFUSLogger {
companion object {
fun log(group: FUSEventGroups, event: String) {
// Not whitelisted for AS
}
fun log(group: FUSEventGroups, event: String, eventData: Map<String, String>) {
// Not whitelisted for AS
}
}
}

View File

@@ -1,3 +0,0 @@
class ProjectConfigurationCollector {
// Not whitelisted
}

View File

@@ -1,88 +0,0 @@
/*
* Copyright 2010-2019 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.idea.actions
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.ide.actions.RevealFileAction
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.MessageType
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.wm.WindowManager
import com.intellij.psi.PsiFile
import com.intellij.ui.BrowserHyperlinkListener
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
import java.io.File
class ShowKotlinGradleDslLogs : IntentionAction, AnAction(), DumbAware {
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
openLogsDirIfPresent(project)
}
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
openLogsDirIfPresent(project)
}
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?) = RevealFileAction.isSupported()
override fun update(e: AnActionEvent) {
val presentation = e.presentation
presentation.isEnabledAndVisible = e.project != null && RevealFileAction.isSupported()
presentation.text = NAME
}
private fun openLogsDirIfPresent(project: Project) {
val logsDir = findLogsDir()
if (logsDir != null) {
RevealFileAction.openDirectory(logsDir)
} else {
val parent = WindowManager.getInstance().getStatusBar(project)?.component
?: WindowManager.getInstance().findVisibleFrame().rootPane
JBPopupFactory.getInstance()
.createHtmlTextBalloonBuilder(
KotlinIdeaGradleBundle.message(
"text.gradle.dsl.logs.cannot.be.found.automatically.see.how.to.find.logs",
gradleTroubleshootingLink
),
MessageType.ERROR,
BrowserHyperlinkListener.INSTANCE
)
.setFadeoutTime(5000)
.createBalloon()
.showInCenterOf(parent)
}
}
/** The way how to find Gradle logs is described here
* @see org.jetbrains.kotlin.idea.actions.ShowKotlinGradleDslLogs.gradleTroubleshootingLink
*/
private fun findLogsDir(): File? {
val userHome = System.getProperty("user.home")
return when {
SystemInfo.isMac -> File("$userHome/Library/Logs/gradle-kotlin-dsl")
SystemInfo.isLinux -> File("$userHome/.gradle-kotlin-dsl/logs")
SystemInfo.isWindows -> File("$userHome/AppData/Local/gradle-kotlin-dsl/log")
else -> null
}.takeIf { it?.exists() == true }
}
override fun startInWriteAction() = false
override fun getText() = NAME
override fun getFamilyName() = NAME
companion object {
private const val gradleTroubleshootingLink = "https://docs.gradle.org/current/userguide/kotlin_dsl.html#troubleshooting"
val NAME = KotlinIdeaGradleBundle.message("action.text.show.kotlin.gradle.dsl.logs.in", RevealFileAction.getFileManagerName())
}
}

View File

@@ -1,8 +0,0 @@
/*
* Copyright 2010-2019 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.gradle
fun KaptImportingTest.isAndroidStudio() = true

View File

@@ -1,8 +0,0 @@
/*
* Copyright 2010-2019 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.idea.codeInsight.gradle
fun isGradleInspectionTestApplicable() = false

View File

@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
import org.jetbrains.plugins.gradle.service.project.open.linkAndRefreshGradleProject
import java.nio.file.Path
// FIX ME WHEN BUNCH 201 REMOVED
class IdeaGradleWizardService(private val project: Project) : ProjectImportingWizardService,
IdeaWizardService {
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean =

View File

@@ -1,15 +0,0 @@
/*
* Copyright 2010-2019 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.tools.projectWizard.wizard.service
import com.intellij.openapi.project.Project
import java.nio.file.Path
class MavenProjectImporter(private val project: Project) {
fun importProject(path: Path) {
// AS does not support Maven
}
}

View File

@@ -95,7 +95,6 @@ abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFix
}
runPostStartupActivitiesOnce(project)
VfsRootAccess.allowRootAccess(project, KtTestUtil.getHomeDirectory())
EditorTracker.getInstance(project)

View File

@@ -1,98 +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.idea.test;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.TempFiles;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.Collection;
@WithMutedInDatabaseRunTest
public abstract class KotlinLightCodeInsightFixtureTestCaseBase extends LightCodeInsightFixtureTestCase {
@NotNull
@Override
public Project getProject() {
return super.getProject();
}
@NotNull
@Override
public Editor getEditor() {
return super.getEditor();
}
@Override
public PsiFile getFile() {
return super.getFile();
}
protected final Collection<File> myFilesToDelete = new THashSet<>();
private final TempFiles myTempFiles = new TempFiles(myFilesToDelete);
@Override
protected void tearDown() throws Exception {
myTempFiles.deleteAll();
super.tearDown();
}
@NotNull
public VirtualFile createTempFile(
@NonNls @NotNull String ext,
@Nullable byte[] bom,
@NonNls @NotNull String content,
@NotNull Charset charset
) throws IOException {
File temp = FileUtil.createTempFile("copy", "." + ext);
setContentOnDisk(temp, bom, content, charset);
myFilesToDelete.add(temp);
final VirtualFile file = getVirtualFile(temp);
assert file != null : temp;
return file;
}
public static void setContentOnDisk(@NotNull File file, @Nullable byte[] bom, @NotNull String content, @NotNull Charset charset)
throws IOException {
FileOutputStream stream = new FileOutputStream(file);
if (bom != null) {
stream.write(bom);
}
try (OutputStreamWriter writer = new OutputStreamWriter(stream, charset)) {
writer.write(content);
}
}
protected static VirtualFile getVirtualFile(@NotNull File file) {
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
}
@Override
protected void runTest() throws Throwable {
//noinspection Convert2MethodRef
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTest());
}
protected boolean isFirPlugin() {
return false;
}
}

View File

@@ -26,7 +26,6 @@ abstract class KotlinLightPlatformCodeInsightFixtureTestCase : LightPlatformCode
override fun setUp() {
super.setUp()
enableKotlinOfficialCodeStyle(project)
runPostStartupActivitiesOnce(project)
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
if (!isFirPlugin()) {
invalidateLibraryCache(project)

View File

@@ -1,137 +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.idea.test;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import kotlin.jvm.functions.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.idea.util.IjPlatformUtil;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.TestJdkKind;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import java.io.File;
public class PluginTestCaseBase {
public static final String TEST_DATA_DIR = "idea/testData";
public static final String TEST_DATA_PROJECT_RELATIVE = "/" + TEST_DATA_DIR;
private PluginTestCaseBase() {
}
@NotNull
public static String getTestDataPathBase() {
return KtTestUtil.getHomeDirectory() + TEST_DATA_PROJECT_RELATIVE;
}
@NotNull
@TestOnly
private static Sdk createMockJdk(@NotNull String name, String path) {
return ((JavaSdkImpl)JavaSdk.getInstance()).createMockJdk(name, path, false);
}
@NotNull
private static Sdk getSdk(String sdkHome, String name) {
ProjectJdkTable table = IjPlatformUtil.getProjectJdkTableSafe();
Sdk existing = table.findJdk(name);
if (existing != null) {
return existing;
}
return JavaSdk.getInstance().createJdk(name, sdkHome, true);
}
@NotNull
public static Sdk mockJdk() {
return getSdk("compiler/testData/mockJDK/jre", "Mock JDK");
}
@NotNull
public static Sdk mockJdk6() {
return getSdk("compiler/testData/mockJDK/jre", "1.6");
}
@NotNull
public static Sdk mockJdk8() {
// Using JDK 6, but with version 1.8
return getSdk("compiler/testData/mockJDK/jre", "1.8");
}
@TestOnly
@NotNull
public static Sdk mockJdk9() {
return getSdk("compiler/testData/mockJDK9/jre", "9");
}
@NotNull
public static Sdk fullJdk() {
String javaHome = System.getProperty("java.home");
assert new File(javaHome).isDirectory();
return getSdk(javaHome, "Full JDK");
}
@NotNull
public static Sdk addJdk(@NotNull Disposable disposable, @NotNull Function0<Sdk> getJdk) {
Sdk jdk = getJdk.invoke();
Sdk[] allJdks = IjPlatformUtil.getProjectJdkTableSafe().getAllJdks();
for (Sdk existingJdk : allJdks) {
if (existingJdk == jdk) {
return existingJdk;
}
}
ApplicationManager.getApplication().runWriteAction(() -> IjPlatformUtil.getProjectJdkTableSafe().addJdk(jdk, disposable));
return jdk;
}
@NotNull
public static Sdk jdk(@NotNull TestJdkKind kind) {
switch (kind) {
case MOCK_JDK:
return mockJdk();
case FULL_JDK_9:
String jre9 = KtTestUtil.getJdk9Home().getPath();
VfsRootAccess.allowRootAccess(jre9);
return getSdk(jre9, "Full JDK 9");
case FULL_JDK:
return fullJdk();
default:
throw new UnsupportedOperationException(kind.toString());
}
}
public static boolean isAllFilesPresentTest(@NotNull String testName) {
return StringUtil.startsWithIgnoreCase(testName, "allFilesPresentIn");
}
@TestOnly
public static void clearSdkTable(@NotNull Disposable disposable) {
Disposer.register(disposable, () -> ApplicationManager.getApplication().runWriteAction(() -> {
ProjectJdkTable jdkTable = IjPlatformUtil.getProjectJdkTableSafe();
for (Sdk sdk : jdkTable.getAllJdks()) {
jdkTable.removeJdk(sdk);
}
}));
}
}

View File

@@ -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.idea.test
import com.intellij.openapi.project.Project
fun runPostStartupActivitiesOnce(project: Project) {
}

View File

@@ -1,15 +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.idea.test
import com.intellij.ide.startup.impl.StartupManagerImpl
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupManager
// FIX ME WHEN BUNCH 201 REMOVED
fun runPostStartupActivitiesOnce(project: Project) {
(StartupManager.getInstance(project) as StartupManagerImpl).runPostStartupActivitiesRegisteredDynamically()
}

View File

@@ -1,120 +0,0 @@
/*
* Copyright 2010-2019 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.idea.debugger.render
import com.intellij.debugger.DebuggerManagerEx
import com.intellij.debugger.engine.DebuggerManagerThreadImpl
import com.intellij.debugger.engine.evaluation.EvaluationContext
import com.intellij.debugger.settings.NodeRendererSettings
import com.intellij.debugger.ui.impl.watch.MessageDescriptor
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl
import com.intellij.debugger.ui.tree.DebuggerTreeNode
import com.intellij.debugger.ui.tree.ValueDescriptor
import com.intellij.debugger.ui.tree.render.ChildrenBuilder
import com.intellij.debugger.ui.tree.render.ClassRenderer
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener
import com.intellij.openapi.diagnostic.Logger
import com.intellij.xdebugger.settings.XDebuggerSettingsManager
import com.sun.jdi.*
import org.jetbrains.kotlin.idea.debugger.*
import org.jetbrains.kotlin.load.java.JvmAbi
import java.util.*
private val LOG = Logger.getInstance(KotlinClassWithDelegatedPropertyRenderer::class.java)
private fun notPreparedClassMessage(referenceType: ReferenceType) =
"$referenceType ${referenceType.isPrepared} ${referenceType.sourceName()}"
class KotlinClassWithDelegatedPropertyRenderer : ClassRenderer() {
private val rendererSettings = NodeRendererSettings.getInstance()
override fun isApplicable(jdiType: Type?): Boolean {
if (!super.isApplicable(jdiType) || jdiType !is ReferenceType || !jdiType.isPrepared || !jdiType.isInKotlinSources()) {
return false
}
try {
return jdiType.allFields().any { it.name().endsWith(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX) }
} catch (notPrepared: ClassNotPreparedException) {
LOG.error(notPreparedClassMessage(jdiType), notPrepared)
}
return false
}
override fun calcLabel(
descriptor: ValueDescriptor,
evaluationContext: EvaluationContext,
listener: DescriptorLabelListener
): String {
val res = calcToStringLabel(descriptor, evaluationContext, listener)
if (res != null) {
return res
}
return super.calcLabel(descriptor, evaluationContext, listener)
}
private fun calcToStringLabel(
descriptor: ValueDescriptor, evaluationContext: EvaluationContext,
listener: DescriptorLabelListener
): String? {
val toStringRenderer = rendererSettings.toStringRenderer
if (toStringRenderer.isEnabled && DebuggerManagerEx.getInstanceEx(evaluationContext.project).context.canRunEvaluation) {
if (toStringRenderer.isApplicable(descriptor.type)) {
return toStringRenderer.calcLabel(descriptor, evaluationContext, listener)
}
}
return null
}
override fun buildChildren(value: Value?, builder: ChildrenBuilder, context: EvaluationContext) {
DebuggerManagerThreadImpl.assertIsManagerThread()
if (value !is ObjectReference) return
val nodeManager = builder.nodeManager!!
val nodeDescriptorFactory = builder.descriptorManager!!
val fields = value.referenceType().allFields()
if (fields.isEmpty()) {
builder.setChildren(listOf(nodeManager.createMessageNode(MessageDescriptor.CLASS_HAS_NO_FIELDS.label)))
return
}
val children = ArrayList<DebuggerTreeNode>()
for (field in fields) {
if (!shouldDisplay(context, value, field)) {
continue
}
val fieldDescriptor = nodeDescriptorFactory.getFieldDescriptor(builder.parentDescriptor, value, field)
if (field.name().endsWith(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX)) {
val shouldRenderDelegatedProperty = KotlinDebuggerSettings.getInstance().renderDelegatedProperties
if (shouldRenderDelegatedProperty && !ToggleKotlinVariablesState.getService().kotlinVariableView) {
children.add(nodeManager.createNode(fieldDescriptor, context))
}
val delegatedPropertyDescriptor = DelegatedPropertyFieldDescriptor(
context.debugProcess.project!!,
value,
field,
shouldRenderDelegatedProperty
)
children.add(nodeManager.createNode(delegatedPropertyDescriptor, context))
} else {
children.add(nodeManager.createNode(fieldDescriptor, context))
}
}
if (XDebuggerSettingsManager.getInstance()!!.dataViewSettings.isSortValues) {
children.sortedWith(NodeManagerImpl.getNodeComparator())
}
builder.setChildren(children)
}
}

View File

@@ -1,299 +0,0 @@
/*
* Copyright 2010-2019 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.idea.debugger.test
import com.intellij.debugger.engine.ContextUtil
import com.intellij.debugger.engine.SuspendContextImpl
import com.intellij.debugger.engine.evaluation.CodeFragmentKind
import com.intellij.debugger.engine.evaluation.EvaluateException
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl
import com.intellij.debugger.impl.DebuggerContextImpl
import com.intellij.debugger.impl.DebuggerContextImpl.createDebuggerContext
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl
import com.intellij.openapi.util.io.FileUtil
import com.intellij.ui.treeStructure.Tree
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup
import com.sun.jdi.ObjectReference
import org.jetbrains.eval4j.ObjectValue
import org.jetbrains.eval4j.Value
import org.jetbrains.eval4j.jdi.asValue
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory
import org.jetbrains.kotlin.idea.debugger.test.preference.DebuggerPreferences
import org.jetbrains.kotlin.idea.debugger.test.util.FramePrinter
import org.jetbrains.kotlin.idea.debugger.test.util.FramePrinterDelegate
import org.jetbrains.kotlin.idea.debugger.test.util.KotlinOutputChecker
import org.jetbrains.kotlin.idea.debugger.test.util.SteppingInstruction
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.InTextDirectivesUtils.findLinesWithPrefixesRemoved
import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes
import org.jetbrains.kotlin.test.KotlinBaseTest
import org.jetbrains.kotlin.test.TargetBackend
import java.io.File
import java.util.concurrent.ConcurrentHashMap
import javax.swing.tree.TreeNode
private data class CodeFragment(val text: String, val result: String, val kind: CodeFragmentKind)
private data class DebugLabel(val name: String, val localName: String)
private class EvaluationTestData(
val instructions: List<SteppingInstruction>,
val fragments: List<CodeFragment>,
val debugLabels: List<DebugLabel>
)
abstract class AbstractKotlinEvaluateExpressionTest : KotlinDescriptorTestCaseWithStepping(), FramePrinterDelegate {
private companion object {
private val ID_PART_REGEX = "id=[0-9]*".toRegex()
}
override val debuggerContext: DebuggerContextImpl
get() = super.debuggerContext
private var isMultipleBreakpointsTest = false
private var framePrinter: FramePrinter? = null
private val exceptions = ConcurrentHashMap<String, Throwable>()
fun doSingleBreakpointTest(path: String) {
isMultipleBreakpointsTest = false
doTest(path)
}
fun doMultipleBreakpointsTest(path: String) {
isMultipleBreakpointsTest = true
doTest(path)
}
override fun doMultiFileTest(files: TestFiles, preferences: DebuggerPreferences) {
val wholeFile = files.wholeFile
val instructions = SteppingInstruction.parse(wholeFile)
val expressions = loadExpressions(wholeFile)
val blocks = loadCodeBlocks(files.originalFile)
val debugLabels = loadDebugLabels(wholeFile)
val data = EvaluationTestData(instructions, expressions + blocks, debugLabels)
framePrinter = FramePrinter(myDebuggerSession, this, preferences, testRootDisposable)
if (isMultipleBreakpointsTest) {
performMultipleBreakpointTest(data)
} else {
performSingleBreakpointTest(data)
}
}
override fun tearDown() {
framePrinter?.close()
framePrinter = null
exceptions.clear()
super.tearDown()
}
private fun performSingleBreakpointTest(data: EvaluationTestData) {
process(data.instructions)
doOnBreakpoint {
createDebugLabels(data.debugLabels)
val exceptions = linkedMapOf<String, Throwable>()
for ((expression, expected, kind) in data.fragments) {
mayThrow(expression) {
evaluate(this, expression, kind, expected)
}
}
val completion = { resume(this) }
framePrinter?.printFrame(completion) ?: completion()
}
finish()
}
private fun performMultipleBreakpointTest(data: EvaluationTestData) {
for ((expression, expected) in data.fragments) {
doOnBreakpoint {
mayThrow(expression) {
try {
evaluate(this, expression, CodeFragmentKind.EXPRESSION, expected)
} finally {
val completion = { resume(this) }
framePrinter?.printFrame(completion) ?: completion()
}
}
}
}
finish()
}
override fun evaluate(suspendContext: SuspendContextImpl, textWithImports: TextWithImportsImpl) {
evaluate(suspendContext, textWithImports, null)
}
private fun evaluate(suspendContext: SuspendContextImpl, text: String, codeFragmentKind: CodeFragmentKind, expectedResult: String?) {
val textWithImports = TextWithImportsImpl(codeFragmentKind, text, "", KotlinFileType.INSTANCE)
return evaluate(suspendContext, textWithImports, expectedResult)
}
private fun evaluate(suspendContext: SuspendContextImpl, item: TextWithImportsImpl, expectedResult: String?) {
val evaluationContext = this.evaluationContext
val sourcePosition = ContextUtil.getSourcePosition(suspendContext)
// Default test debuggerContext doesn't provide a valid stackFrame so we have to create one more for evaluation purposes.
val frameProxy = suspendContext.frameProxy
val threadProxy = frameProxy?.threadProxy()
val debuggerContext = createDebuggerContext(myDebuggerSession, suspendContext, threadProxy, frameProxy)
debuggerContext.initCaches()
val contextElement = ContextUtil.getContextElement(debuggerContext)!!
assert(KotlinCodeFragmentFactory().isContextAccepted(contextElement)) {
val text = runReadAction { contextElement.text }
"KotlinCodeFragmentFactory should be accepted for context element otherwise default evaluator will be called. " +
"ContextElement = $text"
}
contextElement.putCopyableUserData(KotlinCodeFragmentFactory.DEBUG_CONTEXT_FOR_TESTS, debuggerContext)
suspendContext.runActionInSuspendCommand {
try {
val evaluator = runReadAction {
EvaluatorBuilderImpl.build(
item,
contextElement,
sourcePosition,
this@AbstractKotlinEvaluateExpressionTest.project
)
}
?: throw AssertionError("Cannot create an Evaluator for Evaluate Expression")
val value = evaluator.evaluate(evaluationContext)
val actualResult = value.asValue().asString()
if (expectedResult != null) {
assertEquals(
"Evaluate expression returns wrong result for ${item.text}:\n" +
"expected = $expectedResult\n" +
"actual = $actualResult\n",
expectedResult, actualResult
)
}
} catch (e: EvaluateException) {
val expectedMessage = e.message?.replaceFirst(
ID_PART_REGEX,
"id=ID"
)
assertEquals(
"Evaluate expression throws wrong exception for ${item.text}:\n" +
"expected = $expectedResult\n" +
"actual = $expectedMessage\n",
expectedResult,
expectedMessage
)
}
}
}
override fun logDescriptor(descriptor: NodeDescriptorImpl, text: String) {
super.logDescriptor(descriptor, text)
}
override fun expandAll(tree: Tree, runnable: () -> Unit, filter: (TreeNode) -> Boolean, suspendContext: SuspendContextImpl) {
super.expandAll(tree, runnable, HashSet(), filter, suspendContext)
}
private fun mayThrow(expression: String, f: () -> Unit) {
try {
f()
} catch (e: Throwable) {
exceptions[expression] = e
}
}
override fun throwExceptionsIfAny() {
if (exceptions.isNotEmpty()) {
val isIgnored = InTextDirectivesUtils.isIgnoredTarget(
if (useIrBackend()) TargetBackend.JVM_IR else TargetBackend.JVM,
getExpectedOutputFile()
)
if (!isIgnored) {
for (exc in exceptions.values) {
exc.printStackTrace()
}
val expressionsText = exceptions.entries.joinToString("\n") { (k, v) -> "expression: $k, exception: ${v.message}" }
throw AssertionError("Test failed:\n$expressionsText")
} else {
(checker as KotlinOutputChecker).threwException = true
}
}
}
private fun Value.asString(): String {
if (this is ObjectValue && this.value is ObjectReference) {
return this.toString().replaceFirst(ID_PART_REGEX, "id=ID")
}
return this.toString()
}
private fun loadExpressions(testFile: KotlinBaseTest.TestFile): List<CodeFragment> {
val directives = findLinesWithPrefixesRemoved(testFile.content, "// EXPRESSION: ")
val expected = findLinesWithPrefixesRemoved(testFile.content, "// RESULT: ")
assert(directives.size == expected.size) { "Sizes of test directives are different" }
return directives.zip(expected).map { (text, result) -> CodeFragment(text, result, CodeFragmentKind.EXPRESSION) }
}
private fun loadCodeBlocks(wholeFile: File): List<CodeFragment> {
val regexp = (Regex.escape(wholeFile.name) + ".fragment\\d*").toRegex()
val fragmentFiles = wholeFile.parentFile.listFiles { _, name -> regexp.matches(name) } ?: emptyArray()
val codeFragments = mutableListOf<CodeFragment>()
for (fragmentFile in fragmentFiles) {
val contents = FileUtil.loadFile(fragmentFile, true)
val value = findStringWithPrefixes(contents, "// RESULT: ") ?: error("'RESULT' directive is missing in $fragmentFile")
codeFragments += CodeFragment(contents, value, CodeFragmentKind.CODE_BLOCK)
}
return codeFragments
}
private fun loadDebugLabels(testFile: KotlinBaseTest.TestFile): List<DebugLabel> {
return findLinesWithPrefixesRemoved(testFile.content, "// DEBUG_LABEL: ")
.map { text ->
val labelParts = text.split("=")
assert(labelParts.size == 2) { "Wrong format for DEBUG_LABEL directive: // DEBUG_LABEL: {localVariableName} = {labelText}" }
val localName = labelParts[0].trim()
val name = labelParts[1].trim()
DebugLabel(name, localName)
}
}
private fun createDebugLabels(labels: List<DebugLabel>) {
if (labels.isEmpty()) {
return
}
val markupMap = NodeDescriptorImpl.getMarkupMap(debugProcess) ?: return
for ((name, localName) in labels) {
val localVariable = evaluationContext.frameProxy!!.visibleVariableByName(localName)
assert(localVariable != null) { "Cannot find localVariable for label: name = $localName" }
val localVariableValue = evaluationContext.frameProxy!!.getValue(localVariable) as? ObjectReference
assert(localVariableValue != null) { "Local variable $localName should be an ObjectReference" }
markupMap[localVariableValue] = ValueMarkup(name, null, name)
}
}
}

View File

@@ -221,11 +221,7 @@ private class Printer(private val delegate: FramePrinterDelegate, private val co
if (config.shouldRenderExpression() && descriptor is ValueDescriptorImpl) {
val expression = debugProcess.invokeInManagerThread { debuggerContextImpl ->
descriptor.getTreeEvaluation((node as XValueNodeImpl).valueContainer as JavaValue, debuggerContextImpl).let {
// FIX ME WHEN BUNCH 201 REMOVED: getTreeEvaluation in 202 returns CompletableFuture<PsiElement> but in older platforms it's PsiElement
@Suppress("UNCHECKED_CAST")
(it as? CompletableFuture<PsiElement>)?.get() ?: it
} as? PsiExpression
descriptor.getTreeEvaluation((node as XValueNodeImpl).valueContainer as JavaValue, debuggerContextImpl).get()
}
if (expression != null) {

View File

@@ -1,82 +0,0 @@
/*
* Copyright 2010-2019 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.idea.testFramework
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManagerImpl
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import org.jetbrains.plugins.gradle.service.project.open.setupGradleSettings
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.plugins.gradle.settings.GradleSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import org.jetbrains.plugins.gradle.util.GradleLog
import java.io.File
import kotlin.test.assertNotNull
fun refreshGradleProject(projectPath: String, project: Project) {
_importProject(File(projectPath).absolutePath, project)
dispatchAllInvocationEvents()
}
const val GRADLE_JDK_NAME = "Gradle JDK"
/**
* inspired by org.jetbrains.plugins.gradle.service.project.open.importProject(projectDirectory, project)
*/
private fun _importProject(projectPath: String, project: Project) {
GradleLog.LOG.info("Import project at $projectPath")
val projectSdk = ProjectRootManager.getInstance(project).projectSdk
assertNotNull(projectSdk, "project SDK not found for ${project.name} at $projectPath")
val gradleProjectSettings = GradleProjectSettings()
GradleSettings.getInstance(project).gradleVmOptions =
"-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${System.getProperty("user.dir")}"
setupGradleSettings(gradleProjectSettings, projectPath, project, projectSdk)
gradleProjectSettings.gradleJvm = GRADLE_JDK_NAME
GradleSettings.getInstance(project).getLinkedProjectSettings(projectPath)?.let { linkedProjectSettings ->
linkedProjectSettings.gradleJvm = GRADLE_JDK_NAME
}
_attachGradleProjectAndRefresh(gradleProjectSettings, project)
}
/**
* inspired by org.jetbrains.plugins.gradle.service.project.open.attachGradleProjectAndRefresh(gradleProjectSettings, project)
* except everything is MODAL_SYNC
*/
private fun _attachGradleProjectAndRefresh(
gradleProjectSettings: GradleProjectSettings,
project: Project
) {
val externalProjectPath = gradleProjectSettings.externalProjectPath
ExternalProjectsManagerImpl.getInstance(project).runWhenInitialized {
DumbService.getInstance(project).runWhenSmart {
ExternalSystemUtil.ensureToolWindowInitialized(project, GradleConstants.SYSTEM_ID)
}
}
val settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
if (settings.getLinkedProjectSettings(externalProjectPath) == null) {
settings.linkProject(gradleProjectSettings)
}
StatefulTestGradleProjectRefreshCallback(externalProjectPath, project).use { callback ->
ExternalSystemUtil.refreshProject(
externalProjectPath,
ImportSpecBuilder(project, GradleConstants.SYSTEM_ID)
.use(ProgressExecutionMode.MODAL_SYNC)
.callback(callback)
.build()
)
}
}

View File

@@ -1,120 +0,0 @@
/*
* Copyright 2010-2019 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.idea.testFramework
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl
import com.intellij.ide.startup.impl.StartupManagerImpl
import com.intellij.lang.LanguageAnnotators
import com.intellij.lang.LanguageExtensionPoint
import com.intellij.lang.annotation.Annotator
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.impl.NonBlockingReadActionImpl
import com.intellij.openapi.editor.Document
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ex.ProjectManagerEx
import com.intellij.openapi.startup.StartupManager
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.impl.PsiDocumentManagerBase
import com.intellij.testFramework.ExtensionTestUtil
import com.intellij.testFramework.TestApplicationManager
import com.intellij.testFramework.runInEdtAndWait
import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.idea.perf.util.logMessage
import org.jetbrains.kotlin.idea.test.runPostStartupActivitiesOnce
import java.nio.file.Paths
fun commitAllDocuments() {
val fileDocumentManager = FileDocumentManager.getInstance()
runInEdtAndWait {
fileDocumentManager.saveAllDocuments()
}
ProjectManagerEx.getInstanceEx().openProjects.forEach { project ->
val psiDocumentManagerBase = PsiDocumentManager.getInstance(project) as PsiDocumentManagerBase
runInEdtAndWait {
psiDocumentManagerBase.clearUncommittedDocuments()
psiDocumentManagerBase.commitAllDocuments()
}
}
}
fun commitDocument(project: Project, document: Document) {
val psiDocumentManagerBase = PsiDocumentManager.getInstance(project) as PsiDocumentManagerBase
runInEdtAndWait {
psiDocumentManagerBase.commitDocument(document)
}
}
fun saveDocument(document: Document) {
val fileDocumentManager = FileDocumentManager.getInstance()
runInEdtAndWait {
fileDocumentManager.saveDocument(document)
}
}
fun dispatchAllInvocationEvents() {
runInEdtAndWait {
UIUtil.dispatchAllInvocationEvents()
NonBlockingReadActionImpl.waitForAsyncTaskCompletion();
}
}
fun loadProjectWithName(path: String, name: String): Project? =
ProjectManagerEx.getInstanceEx().loadProject(Paths.get(path), name)
fun TestApplicationManager.closeProject(project: Project) {
val name = project.name
val startupManagerImpl = StartupManager.getInstance(project) as StartupManagerImpl
val daemonCodeAnalyzerSettings = DaemonCodeAnalyzerSettings.getInstance()
val daemonCodeAnalyzerImpl = DaemonCodeAnalyzer.getInstance(project) as DaemonCodeAnalyzerImpl
setDataProvider(null)
daemonCodeAnalyzerSettings.isImportHintEnabled = true // return default value to avoid unnecessary save
startupManagerImpl.checkCleared()
daemonCodeAnalyzerImpl.cleanupAfterTest()
logMessage { "project '$name' is about to be closed" }
dispatchAllInvocationEvents()
val projectManagerEx = ProjectManagerEx.getInstanceEx()
projectManagerEx.forceCloseProject(project)
logMessage { "project '$name' successfully closed" }
}
fun runStartupActivities(project: Project) {
with(StartupManager.getInstance(project) as StartupManagerImpl) {
//scheduleInitialVfsRefresh()
runStartupActivities()
}
runPostStartupActivitiesOnce(project)
}
fun waitForAllEditorsFinallyLoaded(project: Project) {
// routing is obsolete in 192
}
fun replaceWithCustomHighlighter(parentDisposable: Disposable, fromImplementationClass: String, toImplementationClass: String) {
val pointName = ExtensionPointName.create<LanguageExtensionPoint<Annotator>>(LanguageAnnotators.EP_NAME.name)
val extensionPoint = pointName.getPoint(null)
val point = LanguageExtensionPoint<Annotator>()
point.language = "kotlin"
point.implementationClass = toImplementationClass
val extensions = extensionPoint.extensions
val filteredExtensions =
extensions.filter { it.language != "kotlin" || it.implementationClass != fromImplementationClass }
.toList()
// custom highlighter is already registered if filteredExtensions has the same size as extensions
if (filteredExtensions.size < extensions.size) {
ExtensionTestUtil.maskExtensions(pointName, filteredExtensions + listOf(point), parentDisposable)
}
}

View File

@@ -1,221 +0,0 @@
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude" version="2" url="http://kotlinlang.org" allow-bundled-update="true">
<id>org.jetbrains.kotlin</id>
<name>Kotlin</name>
<description><![CDATA[
The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<br>
<a href="http://kotlinlang.org/docs/tutorials/getting-started.html">Getting Started in IntelliJ IDEA</a><br>
<a href="http://kotlinlang.org/docs/tutorials/kotlin-android.html">Getting Started in Android Studio</a><br>
<a href="http://slack.kotlinlang.org/">Public Slack</a><br>
<a href="https://youtrack.jetbrains.com/issues/KT">Issue tracker</a><br>
]]></description>
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
<idea-version since-build="201.7223.91" until-build="201.*"/>
<change-notes><![CDATA[
<h3>1.5.0-M2</h3>
<ul>
<li><a href="https://kotlinlang.org/docs/fun-interfaces.html?utm_source=product&utm_medium=link">SAM adapters</a> use `invokedynamic` on the JVM by default.</li>
<li>Deprecation of `-Xjvm-default=enable` and `-Xjvm-default=compatibility` compiler modes and `@JvmDefault` annotation.</li>
<li>Standard library: math functions `floorDiv()` and `mod()`, collection function `firstNotNullOf()`, strict version of String.toBoolean().</li>
</ul>
Learn more about Kotlin 1.5.0-M2 in the <a href="https://github.com/JetBrains/kotlin/releases/tag/v1.5.0-M2/">changelog</a> and <a href="https://blog.jetbrains.com/kotlin/2021/03/kotlin-1-5-0-m2-released/?utm_source=product&utm_medium=link">this blog post</a>.
<br><br>
<h3>1.5.0-M1</h3>
Released: <b>March 3, 2021</b>
<ul>
<li><a href="https://kotlinlang.org/docs/whatsnew14.html?utm_source=product&utm_medium=link#new-jvm-ir-backend">JVM IR backend</a> by default.</li>
<li>New language features by default: inline value classes, sealed interfaces, and JVM records support.</li>
<li>Kotlin/JVM: new default target: 1.8 (1.6 is deprecated), string concatenation uses `invokedynamic` by default.</li>
<li>Kotlin/Native compilation time improvements.</li>
<li>Fixed compiler exceptions.</li>
</ul>
Learn more about Kotlin 1.5.0-M1 in the <a href="https://github.com/JetBrains/kotlin/releases/tag/v1.5.0-M1/">changelog</a>.
<br><br>
<h3>1.4.30</h3>
Released: <b>February 4, 2021</b>
<ul>
<li>Preview of new language features: JVM records support, sealed interfaces, and stable inline classes.</li>
<li>Kotlin/JVM: IR backend is now in Beta.</li>
<li>Kotlin/Native: performance improvements, new `watchosX64` simulator target, support for Xcode 12.2 libraries.</li>
<li>Kotlin/JS: prototype lazy initialization of top-level properties.</li>
<li>Support for Gradle configuration cache.</li>
<li>Standard library API improvements: locale-agnostic API for upper/lowercasing text and clear Char-to-code and Char-to-digit conversions.</li>
</ul>
For more details, see <a href="https://kotlinlang.org/docs/reference/whatsnew1430.html?utm_source=product&utm_medium=link">Whats New in Kotlin 1.4.30</a> and <a href="http://blog.jetbrains.com/kotlin/2021/01/1-4-30-is-released-with-a-new-jvm-backend-and-language-and-multiplatform-features/?utm_source=product&utm_medium=link">this blog post</a>.
<br><br>
<h3>1.4.20</h3>
Released: <b>November 23, 2020</b>
<ul>
<li>Kotlin/JS: New project templates, improved Gradle plugin, experimental <b>compilation with errors mode</b> in the IR compiler.</li>
<li>Kotlin/Native: New escape analysis mechanism, wrapping of Objective-C exceptions, various functional and performance improvements.</li>
<li>IDE: Experimental support for <a href="https://blog.jetbrains.com/idea/2020/03/intellij-idea-2020-1-beta2/">Code Vision</a>, the <b>Redirect input from</b> option in Kotlin run configurations, and more.</li>
<li>JEP 280 (invokedynamic) string concatenation is available on the JVM.</li>
<li>Changes to the layout of multiplatform projects.</li>
<li>Improved CocoaPods support.</li>
<li>Standard library improvements: Extensions for java.nio.file.Path and performance optimizations.</li>
<li>Deprecation of the kotlin-android-extensions compiler plugin. Parcelable implementation generator has moved to the new kotlin-parcelize plugin.</li>
</ul>
For more details, see <a href="https://kotlinlang.org/docs/reference/whatsnew1420.html?utm_source=product&utm_medium=link">Whats New in Kotlin 1.4.20</a> and <a href="https://blog.jetbrains.com/kotlin/2020/11/kotlin-1-4-20-released/?utm_source=product&utm_medium=link">this blog post</a>.
<br><br>
<h3>1.4.0</h3>
Released: <b>August 17, 2020</b>
<ul>
<li>New compiler with better type inference.</li>
<li>IR backends for JVM and JS in Alpha mode (<a href="https://kotlinlang.org/docs/reference/whatsnew14.html#unified-backends-and-extensibility">requires opt-in</a>).</li>
<li>A new flexible Kotlin Project Wizard for easy creation and configuration of different types of projects.</li>
<li>New IDE functionality to debug coroutines.</li>
<li>IDE performance improvements: many actions, such as project opening and autocomplete suggestions now complete up to 4 times faster.</li>
<li>New language features such as SAM conversions, trailing comma, and other.</li>
<li>Type annotations in the JVM bytecode and new modes for generating default interfaces in Kotlin/JVM.</li>
<li>New Gradle DSL for Kotlin/JS.</li>
<li>Improved performance and interop with Swift and Objective-C in Kotlin/Native.</li>
<li>Support for sharing code in several targets thanks to the hierarchical structure in multiplatform projects.</li>
<li>New collection operators, delegated properties improvements, the double-ended queue implementation ArrayDeque, and much more new things in the standard library.</li>
</ul>
For more details, see <a href="https://kotlinlang.org/docs/reference/whatsnew14.html?utm_source=product&utm_medium=link">Whats New in Kotlin 1.4.0</a> and <a href="http://blog.jetbrains.com/kotlin/2020/08/kotlin-1-4-released-with-a-focus-on-quality-and-performance/?utm_source=product&utm_medium=link">this blog post</a>.
<br><br>
To get the most out of the changes and improvements introduced in Kotlin 1.4, join our <a href="https://kotlinlang.org/lp/event-14/">Online Event</a> where you will be able to enjoy four days of Kotlin talks, Q&As with the Kotlin team, and more.
]]>
</change-notes>
<depends>com.intellij.modules.platform</depends>
<depends optional="true" config-file="junit.xml">JUnit</depends>
<depends optional="true" config-file="gradle.xml">com.intellij.gradle</depends>
<depends optional="true" config-file="gradle-java.xml">org.jetbrains.plugins.gradle</depends>
<depends optional="true" config-file="kotlin-gradle-testing.xml">org.jetbrains.plugins.gradle</depends>
<depends optional="true" config-file="gradle-groovy.xml">org.intellij.groovy</depends>
<depends optional="true" config-file="maven.xml">org.jetbrains.idea.maven</depends>
<depends optional="true" config-file="testng-j.xml">TestNG-J</depends>
<depends optional="true" config-file="coverage.xml">Coverage</depends>
<depends optional="true" config-file="i18n.xml">com.intellij.java-i18n</depends>
<depends optional="true" config-file="decompiler.xml">org.jetbrains.java.decompiler</depends>
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
<depends optional="true" config-file="completion-stats.xml">com.intellij.stats.completion</depends>
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
<depends>com.intellij.modules.idea</depends>
<depends>com.intellij.modules.java</depends>
<depends optional="true" config-file="javaScriptDebug.xml">JavaScriptDebugger</depends>
<depends optional="true" config-file="kotlin-copyright.xml">com.intellij.copyright</depends>
<depends optional="true" config-file="injection.xml">org.intellij.intelliLang</depends>
<!-- CIDR-PLUGIN-PLACEHOLDER-END -->
<xi:include href="plugin-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
<!-- CIDR-PLUGIN-EXCLUDE-START -->
<xi:include href="jvm-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="jvm.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="parcelize.xml" xpointer="xpointer(/idea-plugin/*)"/>
<!-- CIDR-PLUGIN-EXCLUDE-END -->
<xi:include href="native-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="native.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="tipsAndTricks.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="extensions/ide.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="kotlinx-serialization.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="scripting-support.xml" xpointer="xpointer(/idea-plugin/*)"/>
<extensionPoints>
<xi:include href="extensions/compiler.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.pluginUpdateVerifier"
interface="org.jetbrains.kotlin.idea.update.PluginUpdateVerifier"/>
</extensionPoints>
<xi:include href="plugin-kotlin-extensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
<extensions defaultExtensionNs="com.intellij.jvm">
<declarationSearcher language="kotlin" implementationClass="org.jetbrains.kotlin.idea.jvm.KotlinDeclarationSearcher"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<pathMacroContributor implementation="org.jetbrains.kotlin.idea.KotlinPluginMacros"/>
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupApplicationService"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.PluginStartupActivity"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupService"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.completion.LookupCancelWatcher"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.caches.KotlinPackageContentModificationListener"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.configuration.KotlinMigrationProjectComponent"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.completion.LookupCancelService"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.configuration.KotlinMigrationProjectService"/>
<highlightVisitor implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightVisitor"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DebugInfoHighlightingPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="2"/>
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.refactoring" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="2"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.j2k" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.editor" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.migrationTool" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.new.wizard" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.gradle.performance" version="1"/>
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.IDESettingsFUSCollector"/>
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.formatter.KotlinFormatterUsageCollector"/>
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.statistics.ProjectConfigurationCollector"/>
<fileTypeUsageSchemaDescriptor schema="Gradle Script"
implementationClass="org.jetbrains.kotlin.idea.core.script.KotlinGradleScriptFileTypeSchemaDetector"/>
<completion.ml.model implementation="org.jetbrains.kotlin.idea.completion.ml.KotlinMLRankingProvider"/>
<completion.ml.contextFeatures language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.completion.ml.KotlinContextFeatureProvider"/>
<suggestedRefactoringSupport language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.refactoring.suggested.KotlinSuggestedRefactoringSupport"/>
<refactoring.moveInnerHandler language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveKotlinInnerHandler"/>
<defaultLiveTemplates file="liveTemplates/Kotlin.xml"/>
<fileType name="Kotlin"
implementationClass="org.jetbrains.kotlin.idea.KotlinFileType"
fieldName="INSTANCE"
language="kotlin"
extensions="kt;kts"/>
<fileType name="ARCHIVE" extensions="klib"/>
<fileType name="KNM"
implementationClass="org.jetbrains.kotlin.idea.klib.KlibMetaFileType"
fieldName="INSTANCE"
extensions="knm"/>
<fileType name="KJSM"
implementationClass="org.jetbrains.kotlin.idea.decompiler.js.KotlinJavaScriptMetaFileType"
fieldName="INSTANCE"
extensions="kjsm"/>
<fileType name="kotlin_builtins"
implementationClass="org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInFileType"
fieldName="INSTANCE"
extensions="kotlin_builtins;kotlin_metadata"/>
<fileType name="kotlin_module"
implementationClass="org.jetbrains.kotlin.idea.KotlinModuleFileType"
fieldName="INSTANCE"
extensions="kotlin_module"/>
</extensions>
</idea-plugin>

View File

@@ -1,203 +0,0 @@
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude" version="2" url="http://kotlinlang.org" allow-bundled-update="true">
<id>org.jetbrains.kotlin</id>
<name>Kotlin</name>
<description><![CDATA[
The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<br>
<a href="http://kotlinlang.org/docs/tutorials/getting-started.html">Getting Started in IntelliJ IDEA</a><br>
<a href="http://kotlinlang.org/docs/tutorials/kotlin-android.html">Getting Started in Android Studio</a><br>
<a href="http://slack.kotlinlang.org/">Public Slack</a><br>
<a href="https://youtrack.jetbrains.com/issues/KT">Issue tracker</a><br>
]]></description>
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
<idea-version since-build="201.7223.91" until-build="201.*"/>
<change-notes><![CDATA[
<h3>1.5.0-M2</h3>
<ul>
<li><a href="https://kotlinlang.org/docs/fun-interfaces.html?utm_source=product&utm_medium=link">SAM adapters</a> use `invokedynamic` on the JVM by default.</li>
<li>Deprecation of `-Xjvm-default=enable` and `-Xjvm-default=compatibility` compiler modes and `@JvmDefault` annotation.</li>
<li>Standard library: math functions `floorDiv()` and `mod()`, collection function `firstNotNullOf()`, strict version of String.toBoolean().</li>
</ul>
Learn more about Kotlin 1.5.0-M2 in the <a href="https://github.com/JetBrains/kotlin/releases/tag/v1.5.0-M2/">changelog</a> and <a href="https://blog.jetbrains.com/kotlin/2021/03/kotlin-1-5-0-m2-released/?utm_source=product&utm_medium=link">this blog post</a>.
<br><br>
<h3>1.5.0-M1</h3>
Released: <b>March 3, 2021</b>
<ul>
<li><a href="https://kotlinlang.org/docs/whatsnew14.html?utm_source=product&utm_medium=link#new-jvm-ir-backend">JVM IR backend</a> by default.</li>
<li>New language features by default: inline value classes, sealed interfaces, and JVM records support.</li>
<li>Kotlin/JVM: new default target: 1.8 (1.6 is deprecated), string concatenation uses `invokedynamic` by default.</li>
<li>Kotlin/Native compilation time improvements.</li>
<li>Fixed compiler exceptions.</li>
</ul>
Learn more about Kotlin 1.5.0-M1 in the <a href="https://github.com/JetBrains/kotlin/releases/tag/v1.5.0-M1/">changelog</a>.
<br><br>
<h3>1.4.30</h3>
Released: <b>February 4, 2021</b>
<ul>
<li>Preview of new language features: JVM records support, sealed interfaces, and stable inline classes.</li>
<li>Kotlin/JVM: IR backend is now in Beta.</li>
<li>Kotlin/Native: performance improvements, new `watchosX64` simulator target, support for Xcode 12.2 libraries.</li>
<li>Kotlin/JS: prototype lazy initialization of top-level properties.</li>
<li>Support for Gradle configuration cache.</li>
<li>Standard library API improvements: locale-agnostic API for upper/lowercasing text and clear Char-to-code and Char-to-digit conversions.</li>
</ul>
For more details, see <a href="https://kotlinlang.org/docs/reference/whatsnew1430.html?utm_source=product&utm_medium=link">Whats New in Kotlin 1.4.30</a> and <a href="http://blog.jetbrains.com/kotlin/2021/01/1-4-30-is-released-with-a-new-jvm-backend-and-language-and-multiplatform-features/?utm_source=product&utm_medium=link">this blog post</a>.
<br><br>
<h3>1.4.20</h3>
Released: <b>November 23, 2020</b>
<ul>
<li>Kotlin/JS: New project templates, improved Gradle plugin, experimental <b>compilation with errors mode</b> in the IR compiler.</li>
<li>Kotlin/Native: New escape analysis mechanism, wrapping of Objective-C exceptions, various functional and performance improvements.</li>
<li>IDE: Experimental support for <a href="https://blog.jetbrains.com/idea/2020/03/intellij-idea-2020-1-beta2/">Code Vision</a>, the <b>Redirect input from</b> option in Kotlin run configurations, and more.</li>
<li>JEP 280 (invokedynamic) string concatenation is available on the JVM.</li>
<li>Changes to the layout of multiplatform projects.</li>
<li>Improved CocoaPods support.</li>
<li>Standard library improvements: Extensions for java.nio.file.Path and performance optimizations.</li>
<li>Deprecation of the kotlin-android-extensions compiler plugin. Parcelable implementation generator has moved to the new kotlin-parcelize plugin.</li>
</ul>
For more details, see <a href="https://kotlinlang.org/docs/reference/whatsnew1420.html?utm_source=product&utm_medium=link">Whats New in Kotlin 1.4.20</a> and <a href="https://blog.jetbrains.com/kotlin/2020/11/kotlin-1-4-20-released/?utm_source=product&utm_medium=link">this blog post</a>.
<br><br>
<h3>1.4.0</h3>
Released: <b>August 17, 2020</b>
<ul>
<li>New compiler with better type inference.</li>
<li>IR backends for JVM and JS in Alpha mode (<a href="https://kotlinlang.org/docs/reference/whatsnew14.html#unified-backends-and-extensibility">requires opt-in</a>).</li>
<li>A new flexible Kotlin Project Wizard for easy creation and configuration of different types of projects.</li>
<li>New IDE functionality to debug coroutines.</li>
<li>IDE performance improvements: many actions, such as project opening and autocomplete suggestions now complete up to 4 times faster.</li>
<li>New language features such as SAM conversions, trailing comma, and other.</li>
<li>Type annotations in the JVM bytecode and new modes for generating default interfaces in Kotlin/JVM.</li>
<li>New Gradle DSL for Kotlin/JS.</li>
<li>Improved performance and interop with Swift and Objective-C in Kotlin/Native.</li>
<li>Support for sharing code in several targets thanks to the hierarchical structure in multiplatform projects.</li>
<li>New collection operators, delegated properties improvements, the double-ended queue implementation ArrayDeque, and much more new things in the standard library.</li>
</ul>
For more details, see <a href="https://kotlinlang.org/docs/reference/whatsnew14.html?utm_source=product&utm_medium=link">Whats New in Kotlin 1.4.0</a> and <a href="http://blog.jetbrains.com/kotlin/2020/08/kotlin-1-4-released-with-a-focus-on-quality-and-performance/?utm_source=product&utm_medium=link">this blog post</a>.
<br><br>
To get the most out of the changes and improvements introduced in Kotlin 1.4, join our <a href="https://kotlinlang.org/lp/event-14/">Online Event</a> where you will be able to enjoy four days of Kotlin talks, Q&As with the Kotlin team, and more.
]]>
</change-notes>
<depends>com.intellij.modules.platform</depends>
<depends>com.intellij.modules.androidstudio</depends>
<depends optional="true" config-file="junit.xml">JUnit</depends>
<depends optional="true" config-file="gradle.xml">com.intellij.gradle</depends>
<depends optional="true" config-file="gradle-java.xml">org.jetbrains.plugins.gradle</depends>
<depends optional="true" config-file="kotlin-gradle-testing.xml">org.jetbrains.plugins.gradle</depends>
<depends optional="true" config-file="gradle-groovy.xml">org.intellij.groovy</depends>
<depends optional="true" config-file="maven.xml">org.jetbrains.idea.maven</depends>
<depends optional="true" config-file="testng-j.xml">TestNG-J</depends>
<depends optional="true" config-file="coverage.xml">Coverage</depends>
<depends optional="true" config-file="i18n.xml">com.intellij.java-i18n</depends>
<depends optional="true" config-file="decompiler.xml">org.jetbrains.java.decompiler</depends>
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
<depends>com.intellij.modules.java</depends>
<depends optional="true" config-file="javaScriptDebug.xml">JavaScriptDebugger</depends>
<depends optional="true" config-file="kotlin-copyright.xml">com.intellij.copyright</depends>
<depends optional="true" config-file="injection.xml">org.intellij.intelliLang</depends>
<!-- CIDR-PLUGIN-PLACEHOLDER-END -->
<xi:include href="plugin-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
<!-- CIDR-PLUGIN-EXCLUDE-START -->
<xi:include href="jvm-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="jvm.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="parcelize.xml" xpointer="xpointer(/idea-plugin/*)"/>
<!-- CIDR-PLUGIN-EXCLUDE-END -->
<xi:include href="native-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="native.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="tipsAndTricks.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="extensions/ide.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="kotlinx-serialization.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="scripting-support.xml" xpointer="xpointer(/idea-plugin/*)"/>
<extensionPoints>
<xi:include href="extensions/compiler.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.pluginUpdateVerifier"
interface="org.jetbrains.kotlin.idea.update.PluginUpdateVerifier"/>
</extensionPoints>
<xi:include href="plugin-kotlin-extensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
<extensions defaultExtensionNs="com.intellij.jvm">
<declarationSearcher language="kotlin" implementationClass="org.jetbrains.kotlin.idea.jvm.KotlinDeclarationSearcher"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<pathMacroContributor implementation="org.jetbrains.kotlin.idea.KotlinPluginMacros"/>
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupApplicationService" />
<postStartupActivity implementation="org.jetbrains.kotlin.idea.PluginStartupActivity"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.PluginStartupService"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.completion.LookupCancelWatcher"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.caches.KotlinPackageContentModificationListener"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.configuration.KotlinMigrationProjectComponent"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.completion.LookupCancelService"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.configuration.KotlinMigrationProjectService"/>
<highlightVisitor implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightVisitor"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.DebugInfoHighlightingPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
<fileTypeUsageSchemaDescriptor schema="Gradle Script" implementationClass="org.jetbrains.kotlin.idea.core.script.KotlinGradleScriptFileTypeSchemaDetector"/>
<completion.ml.model implementation="org.jetbrains.kotlin.idea.completion.ml.KotlinMLRankingProvider"/>
<suggestedRefactoringSupport language="kotlin" implementationClass="org.jetbrains.kotlin.idea.refactoring.suggested.KotlinSuggestedRefactoringSupport"/>
<refactoring.moveInnerHandler language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveKotlinInnerHandler"/>
<defaultLiveTemplates file="liveTemplates/Kotlin.xml"/>
<fileType name="Kotlin"
implementationClass="org.jetbrains.kotlin.idea.KotlinFileType"
fieldName="INSTANCE"
language="kotlin"
extensions="kt;kts"/>
<fileType name="ARCHIVE" extensions="klib"/>
<fileType name="KNM"
implementationClass="org.jetbrains.kotlin.idea.klib.KlibMetaFileType"
fieldName="INSTANCE"
extensions="knm"/>
<fileType name="KJSM"
implementationClass="org.jetbrains.kotlin.idea.decompiler.js.KotlinJavaScriptMetaFileType"
fieldName="INSTANCE"
extensions="kjsm"/>
<fileType name="kotlin_builtins"
implementationClass="org.jetbrains.kotlin.idea.decompiler.builtIns.KotlinBuiltInFileType"
fieldName="INSTANCE"
extensions="kotlin_builtins;kotlin_metadata"/>
<fileType name="kotlin_module"
implementationClass="org.jetbrains.kotlin.idea.KotlinModuleFileType"
fieldName="INSTANCE"
extensions="kotlin_module"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<pluginUpdateVerifier implementation="org.jetbrains.kotlin.idea.update.GooglePluginUpdateVerifier"/>
</extensions>
</idea-plugin>

View File

@@ -1,5 +0,0 @@
<idea-plugin>
<extensions defaultExtensionNs="com.intellij">
<externalAnnotator language="kotlin" implementationClass="org.jetbrains.android.inspections.lint.AndroidLintExternalAnnotator"/>
</extensions>
</idea-plugin>

View File

@@ -1,380 +0,0 @@
/*
* Copyright 2010-2019 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.idea.scratch
import com.intellij.ide.scratch.ScratchFileService
import com.intellij.ide.scratch.ScratchRootType
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.CompilerModuleExtension
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
import com.intellij.testFramework.FileEditorManagerTestCase
import com.intellij.testFramework.MapDataContext
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.TestActionEvent
import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.actions.KOTLIN_WORKSHEET_EXTENSION
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingUtil
import org.jetbrains.kotlin.idea.scratch.actions.ClearScratchAction
import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction
import org.jetbrains.kotlin.idea.scratch.actions.ScratchCompilationSupport
import org.jetbrains.kotlin.idea.scratch.output.InlayScratchFileRenderer
import org.jetbrains.kotlin.idea.scratch.ui.KtScratchFileEditorWithPreview
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.parsing.KotlinParserDefinition.Companion.STD_SCRIPT_SUFFIX
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.MockLibraryUtil
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.utils.PathUtil
import org.junit.Assert
import java.io.File
abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
fun doRightPreviewPanelOutputTest(fileName: String) {
doRightPreviewPanelOutputTest(fileName = fileName, isRepl = false)
}
fun doWorksheetReplTest(fileName: String) {
doInlayOutputTest(fileName = fileName, isRepl = true, isWorksheet = true)
}
fun doScratchReplTest(fileName: String) {
doInlayOutputTest(fileName = fileName, isRepl = true, isWorksheet = false)
}
fun doWorksheetCompilingTest(fileName: String) {
doInlayOutputTest(fileName = fileName, isRepl = false, isWorksheet = true)
}
fun doScratchCompilingTest(fileName: String) {
doInlayOutputTest(fileName = fileName, isRepl = false, isWorksheet = false)
}
fun doWorksheetMultiFileTest(dirName: String) {
doMultiFileTest(dirName, isWorksheet = true)
}
fun doScratchMultiFileTest(dirName: String) {
doMultiFileTest(dirName, isWorksheet = false)
}
private fun doMultiFileTest(dirName: String, isWorksheet: Boolean) {
val mainFileExtension = if (isWorksheet) KOTLIN_WORKSHEET_EXTENSION else STD_SCRIPT_SUFFIX
val javaFiles = arrayListOf<File>()
val kotlinFiles = arrayListOf<File>()
val baseDir = File(testDataPath, dirName)
baseDir.walk().forEach {
if (it.isFile) {
if (it.extension == "java") javaFiles.add(it)
if (it.extension == "kt") kotlinFiles.add(it)
}
}
val testDataPathFile = File(myFixture.testDataPath)
javaFiles.forEach {
myFixture.copyFileToProject(
FileUtil.getRelativePath(testDataPathFile, it)!!,
FileUtil.getRelativePath(baseDir, it)!!
)
}
kotlinFiles.forEach {
myFixture.copyFileToProject(
FileUtil.getRelativePath(testDataPathFile, it)!!,
FileUtil.getRelativePath(baseDir, it)!!
)
}
val outputDir = FileUtil.createTempDirectory(dirName, "")
if (javaFiles.isNotEmpty()) {
val options = listOf("-d", outputDir.path)
KotlinTestUtils.compileJavaFiles(javaFiles, options)
}
MockLibraryUtil.compileKotlin(baseDir.path, outputDir)
PsiTestUtil.setCompilerOutputPath(myFixture.module, outputDir.path, false)
val mainFileName = "$dirName/${getTestName(true)}.$mainFileExtension"
doInlayOutputTest(mainFileName, isRepl = false, isWorksheet = isWorksheet)
launchAction(ClearScratchAction())
doInlayOutputTest(mainFileName, isRepl = true, isWorksheet = isWorksheet)
ModuleRootModificationUtil.updateModel(myFixture.module) { model ->
model.getModuleExtension(CompilerModuleExtension::class.java).inheritCompilerOutputPath(true)
}
}
private fun doInlayOutputTest(fileName: String, isRepl: Boolean, isWorksheet: Boolean) {
configureAndLaunchScratch(fileName = fileName, isRepl = isRepl, isWorksheet = isWorksheet)
val actualOutput = getFileTextWithInlays()
val expectedFile = getExpectedFile(fileName, isRepl, suffix = "after")
KotlinTestUtils.assertEqualsToFile(expectedFile, actualOutput)
}
private fun doRightPreviewPanelOutputTest(fileName: String, isRepl: Boolean) {
configureAndLaunchScratch(fileName = fileName, isRepl = isRepl, isWorksheet = false)
val previewTextWithFoldings = getPreviewTextWithFoldings()
val expectedFile = getExpectedFile(fileName, isRepl, suffix = "preview")
KotlinTestUtils.assertEqualsToFile(expectedFile, previewTextWithFoldings)
}
private fun configureAndLaunchScratch(fileName: String, isRepl: Boolean, isWorksheet: Boolean) {
val sourceFile = File(testDataPath, fileName)
val fileText = sourceFile.readText().inlinePropertiesValues(isRepl)
if (isWorksheet) {
configureWorksheetByText(sourceFile.name, fileText)
} else {
configureScratchByText(sourceFile.name, fileText)
}
if (!KotlinHighlightingUtil.shouldHighlight(myFixture.file)) error("Highlighting for scratch file is switched off")
launchScratch()
waitUntilScratchFinishes(isRepl)
}
private fun getExpectedFile(fileName: String, isRepl: Boolean, suffix: String): File {
val expectedFileName = if (isRepl) {
fileName.replace(".kts", ".repl.$suffix")
} else {
fileName.replace(".kts", ".comp.$suffix")
}
return File(testDataPath, expectedFileName)
}
protected fun String.inlinePropertiesValues(
isRepl: Boolean = false,
isInteractiveMode: Boolean = false
): String {
return replace("~REPL_MODE~", isRepl.toString()).replace("~INTERACTIVE_MODE~", isInteractiveMode.toString())
}
protected fun getFileTextWithInlays(): String {
val doc = myFixture.getDocument(myFixture.file) ?: error("Document for ${myFixture.file.name} is null")
val actualOutput = StringBuilder(myFixture.file.text)
for (line in doc.lineCount - 1 downTo 0) {
getInlays(doc.getLineStartOffset(line), doc.getLineEndOffset(line))
.forEach { inlay ->
val str = inlay.toString()
val offset = doc.getLineEndOffset(line)
actualOutput.insert(
offset,
"${str.takeWhile { it.isWhitespace() }}// ${str.trim()}"
)
}
}
return actualOutput.toString().trim()
}
private fun getPreviewTextWithFoldings(): String {
val scratchFileEditor = getScratchEditorForSelectedFile(myManager, myFixture.file.virtualFile)
?: error("Couldn't find scratch panel")
val previewEditor = scratchFileEditor.getPreviewEditor()
return getFoldingData(previewEditor.editor, withCollapseStatus = false)
}
protected fun getInlays(start: Int = 0, end: Int = myFixture.file.textLength): List<InlayScratchFileRenderer> {
val inlineElementsInRange = myFixture.editor.inlayModel
.getAfterLineEndElementsInRange(start, end)
.filter { it.renderer is InlayScratchFileRenderer }
return inlineElementsInRange.map { it.renderer as InlayScratchFileRenderer }
}
protected fun configureScratchByText(name: String, text: String): ScratchFile {
val scratchVirtualFile = ScratchRootType.getInstance().createScratchFile(
project,
name,
KotlinLanguage.INSTANCE,
text,
ScratchFileService.Option.create_if_missing
) ?: error("Couldn't create scratch file")
myFixture.openFileInEditor(scratchVirtualFile)
ScriptConfigurationManager.updateScriptDependenciesSynchronously(myFixture.file)
val scratchFileEditor = getScratchEditorForSelectedFile(myManager, myFixture.file.virtualFile)
?: error("Couldn't find scratch file")
configureOptions(scratchFileEditor, text, myFixture.module)
return scratchFileEditor.scratchFile
}
protected fun configureWorksheetByText(name: String, text: String): ScratchFile {
val worksheetFile = myFixture.configureByText(name, text).virtualFile
ScriptConfigurationManager.updateScriptDependenciesSynchronously(myFixture.file)
val scratchFileEditor = getScratchEditorForSelectedFile(myManager, myFixture.file.virtualFile)
?: error("Couldn't find scratch panel")
// We want to check that correct module is selected automatically,
// that's why we set `module` to null so it wouldn't be changed
configureOptions(scratchFileEditor, text, null)
return scratchFileEditor.scratchFile
}
protected fun launchScratch() {
val action = RunScratchAction()
launchAction(action)
}
protected fun launchAction(action: AnAction) {
val e = getActionEvent(myFixture.file.virtualFile, action)
action.beforeActionPerformedUpdate(e)
Assert.assertTrue(e.presentation.isEnabled && e.presentation.isVisible)
action.actionPerformed(e)
}
protected fun waitUntilScratchFinishes(shouldStopRepl: Boolean = true) {
UIUtil.dispatchAllInvocationEvents()
val start = System.currentTimeMillis()
// wait until output is displayed in editor or for 1 minute
while (ScratchCompilationSupport.isAnyInProgress()) {
if ((System.currentTimeMillis() - start) > TIME_OUT) {
LOG.warn("Waiting timeout $TIME_OUT ms is exceed")
break
}
Thread.sleep(100)
}
if (shouldStopRepl) stopReplProcess()
UIUtil.dispatchAllInvocationEvents()
}
protected fun stopReplProcess() {
if (myFixture.file != null) {
val scratchFile = getScratchEditorForSelectedFile(myManager, myFixture.file.virtualFile)?.scratchFile
?: error("Couldn't find scratch panel")
scratchFile.replScratchExecutor?.stopAndWait()
}
UIUtil.dispatchAllInvocationEvents()
}
private fun getActionEvent(virtualFile: VirtualFile, action: AnAction): TestActionEvent {
val context = MapDataContext()
context.put(CommonDataKeys.VIRTUAL_FILE_ARRAY, arrayOf(virtualFile))
context.put(CommonDataKeys.PROJECT, project)
context.put(CommonDataKeys.EDITOR, myFixture.editor)
return TestActionEvent(context, action)
}
protected fun testScratchText(): String {
return File(testDataPath, "idea/scripting-support/testData/scratch/custom/test_scratch.kts").readText()
}
override fun getTestDataPath() = KtTestUtil.getHomeDirectory()
override fun getProjectDescriptor(): com.intellij.testFramework.LightProjectDescriptor {
val testName = getTestName(false)
return when {
testName.endsWith("WithKotlinTest") -> INSTANCE_WITH_KOTLIN_TEST
testName.endsWith("NoRuntime") -> INSTANCE_WITHOUT_RUNTIME
testName.endsWith("ScriptRuntime") -> INSTANCE_WITH_SCRIPT_RUNTIME
else -> KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
}
}
override fun setUp() {
super.setUp()
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
PluginTestCaseBase.addJdk(myFixture.projectDisposable) { PluginTestCaseBase.fullJdk() }
}
override fun tearDown() {
super.tearDown()
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory())
ScratchFileService.getInstance().scratchesMapping.mappings.forEach { file, _ ->
runWriteAction { file.delete(this) }
}
}
companion object {
private const val TIME_OUT = 60000 // 1 min
private val INSTANCE_WITH_KOTLIN_TEST = object : KotlinWithJdkAndRuntimeLightProjectDescriptor(
arrayListOf(
ForTestCompileRuntime.runtimeJarForTests(),
PathUtil.kotlinPathsForDistDirectory.kotlinTestPath
)
) {
override fun getSdk() = PluginTestCaseBase.fullJdk()
}
private val INSTANCE_WITHOUT_RUNTIME = object : KotlinLightProjectDescriptor() {
override fun getSdk() = PluginTestCaseBase.fullJdk()
}
private val INSTANCE_WITH_SCRIPT_RUNTIME = object : KotlinWithJdkAndRuntimeLightProjectDescriptor(
arrayListOf(
ForTestCompileRuntime.runtimeJarForTests(),
ForTestCompileRuntime.scriptRuntimeJarForTests()
)
) {
override fun getSdk() = PluginTestCaseBase.fullJdk()
}
fun configureOptions(
scratchFileEditor: KtScratchFileEditorWithPreview,
fileText: String,
module: Module?
) {
val scratchFile = scratchFileEditor.scratchFile
if (InTextDirectivesUtils.getPrefixedBoolean(fileText, "// INTERACTIVE_MODE: ") != true) {
scratchFile.saveOptions { copy(isInteractiveMode = false) }
}
if (InTextDirectivesUtils.getPrefixedBoolean(fileText, "// REPL_MODE: ") == true) {
scratchFile.saveOptions { copy(isRepl = true) }
}
if (module != null && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// NO_MODULE")) {
scratchFile.setModule(module)
}
val isPreviewEnabled = InTextDirectivesUtils.getPrefixedBoolean(fileText, "// PREVIEW_ENABLED: ") == true
scratchFileEditor.setPreviewEnabled(isPreviewEnabled)
}
}
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright 2010-2019 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.idea.scratch
import com.intellij.codeInsight.daemon.LineMarkerInfo
import com.intellij.ide.scratch.ScratchFileService
import com.intellij.ide.scratch.ScratchRootType
import com.intellij.openapi.editor.Document
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiDocumentManager
import com.intellij.testFramework.ExpectedHighlightingData
import com.intellij.testFramework.FileEditorManagerTestCase
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.codeInsight.AbstractLineMarkersTest
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
import org.jetbrains.kotlin.idea.scratch.AbstractScratchRunActionTest.Companion.configureOptions
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.psi.KtFile
import java.io.File
abstract class AbstractScratchLineMarkersTest : FileEditorManagerTestCase() {
fun doScratchTest(path: String) {
val fileText = FileUtil.loadFile(File(path))
val scratchVirtualFile = ScratchRootType.getInstance().createScratchFile(
project,
"scratch.kts",
KotlinLanguage.INSTANCE,
fileText,
ScratchFileService.Option.create_if_missing
) ?: error("Couldn't create scratch file")
myFixture.openFileInEditor(scratchVirtualFile)
ScriptConfigurationManager.updateScriptDependenciesSynchronously(myFixture.file)
val scratchFileEditor = getScratchEditorForSelectedFile(FileEditorManager.getInstance(project), myFixture.file.virtualFile)
?: error("Couldn't find scratch panel")
configureOptions(scratchFileEditor, fileText, null)
val project = myFixture.project
val document = myFixture.editor.document
val data = ExpectedHighlightingData(document, false, false, false, myFixture.file)
data.init()
PsiDocumentManager.getInstance(project).commitAllDocuments()
val markers = doAndCheckHighlighting(document, data, File(path))
AbstractLineMarkersTest.assertNavigationElements(myFixture.project, myFixture.file as KtFile, markers)
}
override fun tearDown() {
super.tearDown()
ScratchFileService.getInstance().scratchesMapping.mappings.forEach { file, _ ->
runWriteAction { file.delete(this) }
}
}
private fun doAndCheckHighlighting(
documentToAnalyze: Document, expectedHighlighting: ExpectedHighlightingData, expectedFile: File
): List<LineMarkerInfo<*>> {
myFixture.doHighlighting()
return AbstractLineMarkersTest.checkHighlighting(myFixture.project, documentToAnalyze, expectedHighlighting, expectedFile)
}
}

View File

@@ -1,3 +0,0 @@
class IDESettingsFUSCollector {
// Not whitelisted
}

View File

@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import java.util.function.Consumer
// FIX ME WHEN BUNCH 201 REMOVED
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase() {
override fun collectDocComments(file: PsiFile, sink: Consumer<PsiDocCommentBase>) {

View File

@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import java.util.function.Consumer
// FIX ME WHEN BUNCH 201 REMOVED
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase() {
override fun collectDocComments(file: PsiFile, sink: Consumer<in PsiDocCommentBase>) {

View File

@@ -34,18 +34,14 @@ import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm;
import org.jetbrains.kotlin.resolve.konan.diagnostics.ErrorsNative;
import static org.jetbrains.kotlin.idea.TestResourceBundleKt.registerAdditionalResourceBundleInTests;
public class PluginStartupActivity implements StartupActivity {
private static final Logger LOG = Logger.getInstance(PluginStartupActivity.class);
@Override
public void runActivity(@NotNull Project project) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
registerAdditionalResourceBundleInTests();
}
StartupCompatKt.runActivity(project);
StartupKt.runActivity(project);
PluginStartupService.Companion.getInstance(project).register(project);
project.getMessageBus().connect().subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {

View File

@@ -1,274 +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.idea.actions
import com.intellij.ide.actions.CreateFileFromTemplateAction
import com.intellij.ide.actions.CreateFileFromTemplateDialog
import com.intellij.ide.actions.CreateFromTemplateAction
import com.intellij.ide.fileTemplates.FileTemplate
import com.intellij.ide.fileTemplates.FileTemplateManager
import com.intellij.ide.fileTemplates.actions.AttributesDefaults
import com.intellij.ide.fileTemplates.ui.CreateFromTemplateDialog
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.actionSystem.LangDataKeys
import com.intellij.openapi.actionSystem.PlatformDataKeys
import com.intellij.openapi.editor.LogicalPosition
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.ui.InputValidatorEx
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiFile
import com.intellij.util.IncorrectOperationException
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.project.getLanguageVersionSettings
import org.jetbrains.kotlin.idea.statistics.FUSEventGroups
import org.jetbrains.kotlin.idea.statistics.KotlinFUSLogger
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.parsing.KotlinParserDefinition.Companion.STD_SCRIPT_SUFFIX
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import java.util.*
class NewKotlinFileAction : CreateFileFromTemplateAction(
KotlinBundle.message("action.new.file.text"),
KotlinBundle.message("action.new.file.description"),
KotlinFileType.INSTANCE.icon
), DumbAware {
override fun postProcess(createdElement: PsiFile?, templateName: String?, customProperties: Map<String, String>?) {
super.postProcess(createdElement, templateName, customProperties)
val module = ModuleUtilCore.findModuleForPsiElement(createdElement!!)
if (createdElement is KtFile) {
if (module != null) {
for (hook in NewKotlinFileHook.EP_NAME.extensions) {
hook.postProcess(createdElement, module)
}
}
val ktClass = createdElement.declarations.singleOrNull() as? KtNamedDeclaration
if (ktClass != null) {
CreateFromTemplateAction.moveCaretAfterNameIdentifier(ktClass)
} else {
val editor = FileEditorManager.getInstance(createdElement.project).selectedTextEditor ?: return
if (editor.document == createdElement.viewProvider.document) {
val lineCount = editor.document.lineCount
if (lineCount > 0) {
editor.caretModel.moveToLogicalPosition(LogicalPosition(lineCount - 1, 0))
}
}
}
}
}
override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) {
builder.setTitle(KotlinBundle.message("action.new.file.dialog.title"))
.addKind(
KotlinBundle.message("action.new.file.dialog.class.title"),
KotlinIcons.CLASS,
"Kotlin Class"
)
.addKind(
KotlinBundle.message("action.new.file.dialog.file.title"),
KotlinFileType.INSTANCE.icon,
"Kotlin File"
)
.addKind(
KotlinBundle.message("action.new.file.dialog.interface.title"),
KotlinIcons.INTERFACE,
"Kotlin Interface"
)
if (project.getLanguageVersionSettings().supportsFeature(LanguageFeature.SealedInterfaces)) {
builder.addKind(
KotlinBundle.message("action.new.file.dialog.sealed.interface.title"),
KotlinIcons.INTERFACE,
"Kotlin Sealed Interface"
)
}
builder.addKind(
KotlinBundle.message("action.new.file.dialog.data.class.title"),
KotlinIcons.CLASS,
"Kotlin Data Class"
)
.addKind(
KotlinBundle.message("action.new.file.dialog.enum.title"),
KotlinIcons.ENUM,
"Kotlin Enum"
)
.addKind(
KotlinBundle.message("action.new.file.dialog.sealed.class.title"),
KotlinIcons.CLASS,
"Kotlin Sealed Class"
)
.addKind(
KotlinBundle.message("action.new.file.dialog.annotation.title"),
KotlinIcons.ANNOTATION,
"Kotlin Annotation"
)
.addKind(
KotlinBundle.message("action.new.file.dialog.object.title"),
KotlinIcons.OBJECT,
"Kotlin Object"
)
builder.setValidator(NameValidator)
}
override fun getActionName(directory: PsiDirectory, newName: String, templateName: String): String =
KotlinBundle.message("action.new.file.text")
override fun isAvailable(dataContext: DataContext): Boolean {
if (super.isAvailable(dataContext)) {
val ideView = LangDataKeys.IDE_VIEW.getData(dataContext)!!
val project = PlatformDataKeys.PROJECT.getData(dataContext)!!
val projectFileIndex = ProjectRootManager.getInstance(project).fileIndex
return ideView.directories.any { projectFileIndex.isInSourceContent(it.virtualFile) }
}
return false
}
override fun hashCode(): Int = 0
override fun equals(other: Any?): Boolean = other is NewKotlinFileAction
override fun startInWriteAction() = false
override fun createFileFromTemplate(name: String, template: FileTemplate, dir: PsiDirectory) =
createFileFromTemplateWithStat(name, template, dir)
companion object {
private object NameValidator : InputValidatorEx {
override fun getErrorText(inputString: String): String? {
if (inputString.trim().isEmpty()) {
return KotlinBundle.message("action.new.file.error.empty.name")
}
val parts: List<String> = inputString.split(*FQNAME_SEPARATORS)
if (parts.any { it.trim().isEmpty() }) {
return KotlinBundle.message("action.new.file.error.empty.name.part")
}
return null
}
override fun checkInput(inputString: String): Boolean = true
override fun canClose(inputString: String): Boolean = getErrorText(inputString) == null
}
@get:TestOnly
val nameValidator: InputValidatorEx
get() = NameValidator
private fun findOrCreateTarget(dir: PsiDirectory, name: String, directorySeparators: CharArray): Pair<String, PsiDirectory> {
var className = removeKotlinExtensionIfPresent(name)
var targetDir = dir
for (splitChar in directorySeparators) {
if (splitChar in className) {
val names = className.trim().split(splitChar)
for (dirName in names.dropLast(1)) {
targetDir = targetDir.findSubdirectory(dirName) ?: runWriteAction {
targetDir.createSubdirectory(dirName)
}
}
className = names.last()
break
}
}
return Pair(className, targetDir)
}
private fun removeKotlinExtensionIfPresent(name: String): String = when {
name.endsWith(".$KOTLIN_WORKSHEET_EXTENSION") -> name.removeSuffix(".$KOTLIN_WORKSHEET_EXTENSION")
name.endsWith(".$STD_SCRIPT_SUFFIX") -> name.removeSuffix(".$STD_SCRIPT_SUFFIX")
name.endsWith(".${KotlinFileType.EXTENSION}") -> name.removeSuffix(".${KotlinFileType.EXTENSION}")
else -> name
}
private fun createFromTemplate(dir: PsiDirectory, className: String, template: FileTemplate): PsiFile? {
val project = dir.project
val defaultProperties = FileTemplateManager.getInstance(project).defaultProperties
val properties = Properties(defaultProperties)
val element = try {
CreateFromTemplateDialog(
project, dir, template,
AttributesDefaults(className).withFixedName(true),
properties
).create()
} catch (e: IncorrectOperationException) {
throw e
} catch (e: Exception) {
LOG.error(e)
return null
}
return element?.containingFile
}
private val FILE_SEPARATORS = charArrayOf('/', '\\')
private val FQNAME_SEPARATORS = charArrayOf('/', '\\', '.')
fun createFileFromTemplateWithStat(name: String, template: FileTemplate, dir: PsiDirectory): PsiFile? {
KotlinFUSLogger.log(FUSEventGroups.NewFileTemplate, template.name)
return createFileFromTemplate(name, template, dir)
}
fun createFileFromTemplate(name: String, template: FileTemplate, dir: PsiDirectory): PsiFile? {
val directorySeparators = when (template.name) {
"Kotlin File" -> FILE_SEPARATORS
else -> FQNAME_SEPARATORS
}
val (className, targetDir) = findOrCreateTarget(dir, name, directorySeparators)
val service = DumbService.getInstance(dir.project)
service.isAlternativeResolveEnabled = true
try {
val psiFile = createFromTemplate(targetDir, className, template)
if (psiFile is KtFile) {
val singleClass = psiFile.declarations.singleOrNull() as? KtClass
if (singleClass != null && !singleClass.isEnum() && !singleClass.isInterface() && name.contains("Abstract")) {
runWriteAction {
singleClass.addModifier(KtTokens.ABSTRACT_KEYWORD)
}
}
}
return psiFile
} finally {
service.isAlternativeResolveEnabled = false
}
}
}
}
abstract class NewKotlinFileHook {
companion object {
val EP_NAME: ExtensionPointName<NewKotlinFileHook> =
ExtensionPointName.create<NewKotlinFileHook>("org.jetbrains.kotlin.newFileHook")
}
abstract fun postProcess(createdElement: KtFile, module: Module)
}

View File

@@ -1,15 +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.idea.codeInsight
import com.intellij.ide.ui.UISettings
import com.intellij.ui.breadcrumbs.BreadcrumbsProvider
// FIX ME WHEN BUNCH 201 REMOVED
abstract class BreadcrumbsProviderCompatBase : BreadcrumbsProvider {
override fun isShownByDefault(): Boolean =
!UISettings.instance.showMembersInNavigationBar
}

View File

@@ -5,11 +5,13 @@
package org.jetbrains.kotlin.idea.codeInsight
import com.intellij.ide.ui.UISettings
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.IndexNotReadyException
import com.intellij.psi.ElementDescriptionUtil
import com.intellij.psi.PsiElement
import com.intellij.refactoring.util.RefactoringDescriptionLocation
import com.intellij.ui.breadcrumbs.BreadcrumbsProvider
import com.intellij.usageView.UsageViewShortNameLocation
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.idea.KotlinBundle
@@ -23,8 +25,7 @@ import org.jetbrains.kotlin.renderer.render
import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses
import kotlin.reflect.KClass
// FIX ME WHEN BUNCH 201 REMOVED
class KotlinBreadcrumbsInfoProvider : BreadcrumbsProviderCompatBase() {
class KotlinBreadcrumbsInfoProvider : BreadcrumbsProvider {
private abstract class ElementHandler<TElement : KtElement>(val type: KClass<TElement>) {
abstract fun elementInfo(element: TElement): String
abstract fun elementTooltip(element: TElement): String
@@ -428,6 +429,9 @@ class KotlinBreadcrumbsInfoProvider : BreadcrumbsProviderCompatBase() {
}
}
override fun isShownByDefault(): Boolean =
!UISettings.instance.showMembersInNavigationBar
private companion object {
enum class TextKind(val maxTextLength: Int) {
INFO(16), TOOLTIP(100)

View File

@@ -1,16 +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.idea.configuration
internal object MLCompletionForKotlin {
const val isAvailable: Boolean = false
var isEnabled: Boolean
get() = false
set(value) {
throw UnsupportedOperationException()
}
}

View File

@@ -1,174 +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.idea.highlighter
import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerBase
import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactoryBase
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.tree.TokenSet
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.Consumer
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsResultOfLambda
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class KotlinHighlightExitPointsHandlerFactory : HighlightUsagesHandlerFactoryBase() {
companion object {
private val RETURN_AND_THROW = TokenSet.create(KtTokens.RETURN_KEYWORD, KtTokens.THROW_KEYWORD)
private fun getOnReturnOrThrowUsageHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? {
if (target !is LeafPsiElement || target.elementType !in RETURN_AND_THROW) {
return null
}
val returnOrThrow = PsiTreeUtil.getParentOfType<KtExpression>(
target,
KtReturnExpression::class.java,
KtThrowExpression::class.java
) ?: return null
return OnExitUsagesHandler(editor, file, returnOrThrow)
}
private fun getOnLambdaCallUsageHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? {
if (target !is LeafPsiElement || target.elementType != KtTokens.IDENTIFIER) {
return null
}
val refExpr = target.parent as? KtNameReferenceExpression ?: return null
val call = refExpr.parent as? KtCallExpression ?: return null
if (call.calleeExpression != refExpr) return null
val lambda = call.lambdaArguments.singleOrNull() ?: return null
val literal = lambda.getLambdaExpression()?.functionLiteral ?: return null
return OnExitUsagesHandler(editor, file, literal, highlightReferences = true)
}
}
override fun createHighlightUsagesHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? {
return getOnReturnOrThrowUsageHandler(editor, file, target)
?: getOnLambdaCallUsageHandler(editor, file, target)
}
private class OnExitUsagesHandler(editor: Editor, file: PsiFile, val target: KtExpression, val highlightReferences: Boolean = false) :
HighlightUsagesHandlerBase<PsiElement>(editor, file) {
override fun getTargets() = listOf(target)
override fun selectTargets(targets: MutableList<PsiElement>, selectionConsumer: Consumer<MutableList<PsiElement>>) {
selectionConsumer.consume(targets)
}
override fun computeUsages(targets: MutableList<PsiElement>?) {
val relevantFunction: KtDeclarationWithBody? =
if (target is KtFunctionLiteral) {
target
} else {
target.getRelevantDeclaration()
}
relevantFunction?.accept(object : KtVisitorVoid() {
override fun visitKtElement(element: KtElement) {
element.acceptChildren(this)
}
override fun visitExpression(expression: KtExpression) {
if (relevantFunction is KtFunctionLiteral) {
if (occurrenceForFunctionLiteralReturnExpression(expression)) {
return
}
}
super.visitExpression(expression)
}
private fun occurrenceForFunctionLiteralReturnExpression(expression: KtExpression): Boolean {
if (!KtPsiUtil.isStatement(expression)) return false
if (expression is KtIfExpression || expression is KtWhenExpression || expression is KtBlockExpression) {
return false
}
val bindingContext = expression.analyze(BodyResolveMode.FULL)
if (!expression.isUsedAsResultOfLambda(bindingContext)) {
return false
}
if (expression.getRelevantDeclaration() != relevantFunction) {
return false
}
addOccurrence(expression)
return true
}
private fun visitReturnOrThrow(expression: KtExpression) {
if (expression.getRelevantDeclaration() == relevantFunction) {
addOccurrence(expression)
}
}
override fun visitReturnExpression(expression: KtReturnExpression) {
visitReturnOrThrow(expression)
}
override fun visitThrowExpression(expression: KtThrowExpression) {
visitReturnOrThrow(expression)
}
})
}
override fun highlightReferences() = highlightReferences
}
}
private fun KtExpression.getRelevantDeclaration(): KtDeclarationWithBody? {
if (this is KtReturnExpression) {
(this.getTargetLabel()?.mainReference?.resolve() as? KtFunction)?.let {
return it
}
}
if (this is KtThrowExpression || this is KtReturnExpression) {
for (parent in parents) {
if (parent is KtDeclarationWithBody) {
if (parent is KtPropertyAccessor) {
return parent
}
if (InlineUtil.canBeInlineArgument(parent) &&
!InlineUtil.isInlinedArgument(parent as KtFunction, parent.analyze(BodyResolveMode.FULL), false)
) {
return parent
}
}
}
return null
}
return parents.filterIsInstance<KtDeclarationWithBody>().firstOrNull()
}

View File

@@ -1,58 +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.idea.highlighter
import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerBase
import com.intellij.codeInsight.highlighting.HighlightUsagesHandlerFactoryBase
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.util.Consumer
import org.jetbrains.kotlin.idea.intentions.getLambdaByImplicitItReference
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.KtTreeVisitorVoid
class KotlinHighlightImplicitItHandlerFactory : HighlightUsagesHandlerFactoryBase() {
override fun createHighlightUsagesHandler(editor: Editor, file: PsiFile, target: PsiElement): HighlightUsagesHandlerBase<*>? {
if (!(target is LeafPsiElement && target.elementType == KtTokens.IDENTIFIER)) return null
val refExpr = target.parent as? KtNameReferenceExpression ?: return null
val lambda = getLambdaByImplicitItReference(refExpr) ?: return null
return object : HighlightUsagesHandlerBase<KtNameReferenceExpression>(editor, file) {
override fun getTargets() = listOf(refExpr)
override fun selectTargets(
targets: MutableList<KtNameReferenceExpression>,
selectionConsumer: Consumer<MutableList<KtNameReferenceExpression>>
) = selectionConsumer.consume(targets)
override fun computeUsages(targets: MutableList<KtNameReferenceExpression>?) {
lambda.accept(
object : KtTreeVisitorVoid() {
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
if (expression is KtNameReferenceExpression && getLambdaByImplicitItReference(expression) == lambda) {
addOccurrence(expression)
}
}
}
)
}
}
}
}

View File

@@ -1,189 +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.idea.highlighter
import com.intellij.codeHighlighting.Pass
import com.intellij.codeInsight.daemon.LineMarkerInfo
import com.intellij.codeInsight.daemon.LineMarkerProvider
import com.intellij.icons.AllIcons
import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.highlighter.markers.LineMarkerInfos
import org.jetbrains.kotlin.idea.inspections.RecursivePropertyAccessorInspection
import org.jetbrains.kotlin.idea.util.getReceiverTargetDescriptor
import org.jetbrains.kotlin.lexer.KtToken
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.util.*
class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
override fun getLineMarkerInfo(element: PsiElement) = null
override fun collectSlowLineMarkers(elements: MutableList<PsiElement>, result: LineMarkerInfos) {
val markedLineNumbers = HashSet<Int>()
for (element in elements) {
ProgressManager.checkCanceled()
if (element is KtElement) {
val lineNumber = element.getLineNumber()
if (lineNumber !in markedLineNumbers && isRecursiveCall(element)) {
markedLineNumbers.add(lineNumber)
result.add(RecursiveMethodCallMarkerInfo(getElementForLineMark(element)))
}
}
}
}
private fun getEnclosingFunction(element: KtElement, stopOnNonInlinedLambdas: Boolean): KtNamedFunction? {
for (parent in element.parents) {
when (parent) {
is KtFunctionLiteral -> if (stopOnNonInlinedLambdas && !InlineUtil.isInlinedArgument(
parent,
parent.analyze(),
false
)
) return null
is KtNamedFunction -> {
when (parent.parent) {
is KtBlockExpression, is KtClassBody, is KtFile, is KtScript -> return parent
else -> if (stopOnNonInlinedLambdas && !InlineUtil.isInlinedArgument(parent, parent.analyze(), false)) return null
}
}
is KtClassOrObject -> return null
}
}
return null
}
private fun isRecursiveCall(element: KtElement): Boolean {
if (RecursivePropertyAccessorInspection.isRecursivePropertyAccess(element)) return true
if (RecursivePropertyAccessorInspection.isRecursiveSyntheticPropertyAccess(element)) return true
// Fast check for names without resolve
val resolveName = getCallNameFromPsi(element) ?: return false
val enclosingFunction = getEnclosingFunction(element, false) ?: return false
val enclosingFunctionName = enclosingFunction.name
if (enclosingFunctionName != OperatorNameConventions.INVOKE.asString()
&& enclosingFunctionName != resolveName.asString()
) return false
// Check that there were no not-inlined lambdas on the way to enclosing function
if (enclosingFunction != getEnclosingFunction(element, true)) return false
val bindingContext = element.analyze()
val enclosingFunctionDescriptor = bindingContext[BindingContext.FUNCTION, enclosingFunction] ?: return false
val call = bindingContext[BindingContext.CALL, element] ?: return false
val resolvedCall = bindingContext[BindingContext.RESOLVED_CALL, call] ?: return false
if (resolvedCall.candidateDescriptor.original != enclosingFunctionDescriptor) return false
fun isDifferentReceiver(receiver: Receiver?): Boolean {
if (receiver !is ReceiverValue) return false
val receiverOwner = receiver.getReceiverTargetDescriptor(bindingContext) ?: return true
return when (receiverOwner) {
is SimpleFunctionDescriptor -> receiverOwner != enclosingFunctionDescriptor
is ClassDescriptor -> receiverOwner != enclosingFunctionDescriptor.containingDeclaration
else -> return true
}
}
if (isDifferentReceiver(resolvedCall.dispatchReceiver)) return false
return true
}
private class RecursiveMethodCallMarkerInfo(callElement: PsiElement) : LineMarkerInfo<PsiElement>(
callElement,
callElement.textRange,
AllIcons.Gutter.RecursiveMethod,
Pass.LINE_MARKERS,
{ KotlinBundle.message("highlighter.tool.tip.text.recursive.call") },
null,
GutterIconRenderer.Alignment.RIGHT
) {
override fun createGutterRenderer(): GutterIconRenderer? {
return object : LineMarkerInfo.LineMarkerGutterIconRenderer<PsiElement>(this) {
override fun getClickAction() = null // to place breakpoint on mouse click
}
}
}
}
internal fun getElementForLineMark(callElement: PsiElement): PsiElement =
when (callElement) {
is KtSimpleNameExpression -> callElement.getReferencedNameElement()
else ->
// a fallback,
//but who knows what to reference in KtArrayAccessExpression ?
generateSequence(callElement, { it.firstChild }).last()
}
private fun PsiElement.getLineNumber(): Int {
return PsiDocumentManager.getInstance(project).getDocument(containingFile)!!.getLineNumber(textOffset)
}
private fun getCallNameFromPsi(element: KtElement): Name? {
when (element) {
is KtSimpleNameExpression -> {
val elementParent = element.getParent()
when (elementParent) {
is KtCallExpression -> return Name.identifier(element.getText())
is KtOperationExpression -> {
val operationReference = elementParent.operationReference
if (element == operationReference) {
val node = operationReference.getReferencedNameElementType()
return if (node is KtToken) {
val conventionName = if (elementParent is KtPrefixExpression)
OperatorConventions.getNameForOperationSymbol(node, true, false)
else
OperatorConventions.getNameForOperationSymbol(node)
conventionName ?: Name.identifier(element.getText())
} else {
Name.identifier(element.getText())
}
}
}
}
}
is KtArrayAccessExpression ->
return OperatorNameConventions.GET
is KtThisExpression ->
if (element.getParent() is KtCallExpression) {
return OperatorNameConventions.INVOKE
}
}
return null
}

View File

@@ -1,126 +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.idea.highlighter
import com.intellij.codeHighlighting.Pass
import com.intellij.codeInsight.daemon.LineMarkerInfo
import com.intellij.codeInsight.daemon.LineMarkerProvider
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.descriptors.accessors
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.highlighter.markers.LineMarkerInfos
import org.jetbrains.kotlin.idea.refactoring.getLineNumber
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.*
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
private class SuspendCallMarkerInfo(callElement: PsiElement, message: String) : LineMarkerInfo<PsiElement>(
callElement,
callElement.textRange,
KotlinIcons.SUSPEND_CALL,
Pass.LINE_MARKERS,
{ message },
null,
GutterIconRenderer.Alignment.RIGHT
) {
override fun createGutterRenderer(): GutterIconRenderer? {
return object : LineMarkerInfo.LineMarkerGutterIconRenderer<PsiElement>(this) {
override fun getClickAction(): AnAction? = null
}
}
}
override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<*>? = null
override fun collectSlowLineMarkers(
elements: MutableList<PsiElement>,
result: LineMarkerInfos
) {
val markedLineNumbers = HashSet<Int>()
for (element in elements) {
ProgressManager.checkCanceled()
if (element !is KtExpression) continue
val containingFile = element.containingFile
if (containingFile !is KtFile || containingFile is KtCodeFragment) {
continue
}
val lineNumber = element.getLineNumber()
if (lineNumber in markedLineNumbers) continue
if (!element.hasSuspendCalls()) continue
markedLineNumbers += lineNumber
result += if (element is KtForExpression) {
SuspendCallMarkerInfo(
getElementForLineMark(element.loopRange!!),
KotlinBundle.message("highlighter.message.suspending.iteration")
)
} else {
SuspendCallMarkerInfo(getElementForLineMark(element), KotlinBundle.message("highlighter.message.suspend.function.call"))
}
}
}
}
private fun KtExpression.isValidCandidateExpression(): Boolean {
if (this is KtParenthesizedExpression) return false
if (this is KtOperationReferenceExpression || this is KtForExpression || this is KtProperty || this is KtNameReferenceExpression) return true
val parent = parent
if (parent is KtCallExpression && parent.calleeExpression == this) return true
if (this is KtCallExpression && (calleeExpression is KtCallExpression || calleeExpression is KtParenthesizedExpression)) return true
return false
}
fun KtExpression.hasSuspendCalls(bindingContext: BindingContext = analyze(BodyResolveMode.PARTIAL)): Boolean {
if (!isValidCandidateExpression()) return false
return when (this) {
is KtForExpression -> {
val iteratorResolvedCall = bindingContext[LOOP_RANGE_ITERATOR_RESOLVED_CALL, loopRange]
val loopRangeHasNextResolvedCall = bindingContext[LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, loopRange]
val loopRangeNextResolvedCall = bindingContext[LOOP_RANGE_NEXT_RESOLVED_CALL, loopRange]
listOf(iteratorResolvedCall, loopRangeHasNextResolvedCall, loopRangeNextResolvedCall).any {
it?.resultingDescriptor?.isSuspend == true
}
}
is KtProperty -> {
if (hasDelegateExpression()) {
val variableDescriptor = bindingContext[DECLARATION_TO_DESCRIPTOR, this] as? VariableDescriptorWithAccessors
val accessors = variableDescriptor?.accessors ?: emptyList()
accessors.any { accessor ->
val delegatedFunctionDescriptor = bindingContext[DELEGATED_PROPERTY_RESOLVED_CALL, accessor]?.resultingDescriptor
delegatedFunctionDescriptor?.isSuspend == true
}
} else {
false
}
}
else -> {
val resolvedCall = getResolvedCall(bindingContext)
if ((resolvedCall?.resultingDescriptor as? FunctionDescriptor)?.isSuspend == true) true
else {
val propertyDescriptor = resolvedCall?.resultingDescriptor as? PropertyDescriptor
val s = propertyDescriptor?.fqNameSafe?.asString()
s?.startsWith("kotlin.coroutines.") == true && s.endsWith(".coroutineContext")
}
}
}
}

View File

@@ -1,10 +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.idea.highlighter.markers
import com.intellij.codeInsight.daemon.LineMarkerInfo
typealias LineMarkerInfos = MutableCollection<LineMarkerInfo<*>>

View File

@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.highlighter.dsl.DslHighlighterExtension
import javax.swing.Icon
// FIX ME WHEN BUNCH as41 REMOVED
// FIX ME WHEN BUNCH as42 REMOVED
internal fun createDslStyleIcon(styleId: Int): Icon {
val globalScheme = EditorColorsManager.getInstance().globalScheme
val markersColor = globalScheme.getAttributes(DslHighlighterExtension.styleById(styleId)).foregroundColor

View File

@@ -1,14 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. 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.idea.highlighter.markers
import com.intellij.icons.AllIcons
import javax.swing.Icon
// FIX ME WHEN BUNCH as41 REMOVED
internal fun createDslStyleIcon(styleId: Int): Icon {
return AllIcons.Gutter.Colors
}

View File

@@ -1,192 +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.idea.inspections
import com.intellij.application.options.CodeStyle
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.codeStyle.CodeStyleManager
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.formatter.TrailingCommaVisitor
import org.jetbrains.kotlin.idea.formatter.kotlinCustomSettings
import org.jetbrains.kotlin.idea.formatter.trailingComma.*
import org.jetbrains.kotlin.idea.formatter.trailingCommaAllowedInModule
import org.jetbrains.kotlin.idea.util.isComma
import org.jetbrains.kotlin.idea.util.isLineBreak
import org.jetbrains.kotlin.idea.util.leafIgnoringWhitespaceAndComments
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.psiUtil.*
import javax.swing.JComponent
import kotlin.properties.Delegates
class TrailingCommaInspection(
@JvmField
var addCommaWarning: Boolean = false
) : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor = object : TrailingCommaVisitor() {
override val recursively: Boolean = false
private var useTrailingComma by Delegates.notNull<Boolean>()
override fun process(trailingCommaContext: TrailingCommaContext) {
val element = trailingCommaContext.ktElement
val kotlinCustomSettings = CodeStyle.getSettings(element.project).kotlinCustomSettings
useTrailingComma = kotlinCustomSettings.addTrailingCommaIsAllowedFor(element)
when (trailingCommaContext.state) {
TrailingCommaState.MISSING, TrailingCommaState.EXISTS -> {
checkCommaPosition(element)
checkLineBreaks(element)
}
else -> Unit
}
checkTrailingComma(trailingCommaContext)
}
private fun checkLineBreaks(commaOwner: KtElement) {
val first = TrailingCommaHelper.elementBeforeFirstElement(commaOwner)
if (first?.nextLeaf(true)?.isLineBreak() == false) {
first.nextSibling?.let {
registerProblemForLineBreak(commaOwner, it, ProblemHighlightType.INFORMATION)
}
}
val last = TrailingCommaHelper.elementAfterLastElement(commaOwner)
if (last?.prevLeaf(true)?.isLineBreak() == false) {
registerProblemForLineBreak(
commaOwner,
last,
if (addCommaWarning) ProblemHighlightType.GENERIC_ERROR_OR_WARNING else ProblemHighlightType.INFORMATION,
)
}
}
private fun checkCommaPosition(commaOwner: KtElement) {
for (invalidComma in TrailingCommaHelper.findInvalidCommas(commaOwner)) {
reportProblem(
invalidComma,
KotlinBundle.message("inspection.trailing.comma.comma.loses.the.advantages.in.this.position"),
KotlinBundle.message("inspection.trailing.comma.fix.comma.position")
)
}
}
private fun checkTrailingComma(trailingCommaContext: TrailingCommaContext) {
val commaOwner = trailingCommaContext.ktElement
val trailingCommaOrLastElement = TrailingCommaHelper.trailingCommaOrLastElement(commaOwner) ?: return
when (trailingCommaContext.state) {
TrailingCommaState.MISSING -> {
if (!trailingCommaAllowedInModule(commaOwner)) return
reportProblem(
trailingCommaOrLastElement,
KotlinBundle.message("inspection.trailing.comma.missing.trailing.comma"),
KotlinBundle.message("inspection.trailing.comma.add.trailing.comma"),
if (addCommaWarning) ProblemHighlightType.GENERIC_ERROR_OR_WARNING else ProblemHighlightType.INFORMATION,
)
}
TrailingCommaState.REDUNDANT -> {
reportProblem(
trailingCommaOrLastElement,
KotlinBundle.message("inspection.trailing.comma.useless.trailing.comma"),
KotlinBundle.message("inspection.trailing.comma.remove.trailing.comma"),
ProblemHighlightType.LIKE_UNUSED_SYMBOL,
checkTrailingCommaSettings = false,
)
}
else -> Unit
}
}
private fun reportProblem(
commaOrElement: PsiElement,
message: String,
fixMessage: String,
highlightType: ProblemHighlightType = ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
checkTrailingCommaSettings: Boolean = true,
) {
val commaOwner = commaOrElement.parent as KtElement
// case for KtFunctionLiteral, where PsiWhiteSpace after KtTypeParameterList isn't included in this list
val problemOwner = commaOwner.parent
holder.registerProblem(
problemOwner,
message,
highlightType.applyCondition(!checkTrailingCommaSettings || useTrailingComma),
commaOrElement.textRangeOfCommaOrSymbolAfter.shiftLeft(problemOwner.startOffset),
createQuickFix(fixMessage, commaOwner),
)
}
private fun registerProblemForLineBreak(
commaOwner: KtElement,
elementForTextRange: PsiElement,
highlightType: ProblemHighlightType,
) {
val problemElement = commaOwner.parent
holder.registerProblem(
problemElement,
KotlinBundle.message("inspection.trailing.comma.missing.line.break"),
highlightType.applyCondition(useTrailingComma),
TextRange.from(elementForTextRange.startOffset, 1).shiftLeft(problemElement.startOffset),
createQuickFix(KotlinBundle.message("inspection.trailing.comma.add.line.break"), commaOwner),
)
}
private fun ProblemHighlightType.applyCondition(condition: Boolean): ProblemHighlightType = when {
ApplicationManager.getApplication().isUnitTestMode -> ProblemHighlightType.GENERIC_ERROR_OR_WARNING
condition -> this
else -> ProblemHighlightType.INFORMATION
}
private fun createQuickFix(
fixMessage: String,
commaOwner: KtElement,
): LocalQuickFix = object : LocalQuickFix {
val commaOwnerPointer = commaOwner.createSmartPointer()
override fun getFamilyName(): String = fixMessage
override fun applyFix(project: Project, problemDescriptor: ProblemDescriptor) {
val element = commaOwnerPointer.element ?: return
val range = createFormatterTextRange(element)
val settings = CodeStyle.getSettings(project).clone()
settings.kotlinCustomSettings.ALLOW_TRAILING_COMMA = true
settings.kotlinCustomSettings.ALLOW_TRAILING_COMMA_ON_CALL_SITE = true
CodeStyle.doWithTemporarySettings(project, settings) {
CodeStyleManager.getInstance(project).reformatRange(element, range.startOffset, range.endOffset)
}
}
}
private fun createFormatterTextRange(commaOwner: KtElement): TextRange {
val startElement = TrailingCommaHelper.elementBeforeFirstElement(commaOwner) ?: commaOwner
val endElement = TrailingCommaHelper.elementAfterLastElement(commaOwner) ?: commaOwner
return TextRange.create(startElement.startOffset, endElement.endOffset)
}
private val PsiElement.textRangeOfCommaOrSymbolAfter: TextRange
get() {
val textRange = textRange
if (isComma) return textRange
return nextLeaf()?.leafIgnoringWhitespaceAndComments(false)?.endOffset?.takeIf { it > 0 }?.let {
TextRange.create(it - 1, it).intersection(textRange)
} ?: TextRange.create(textRange.endOffset - 1, textRange.endOffset)
}
}
override fun createOptionsPanel(): JComponent? {
val panel = MultipleCheckboxOptionsPanel(this)
panel.addCheckbox(KotlinBundle.message("inspection.trailing.comma.report.also.a.missing.comma"), "addCommaWarning")
return panel
}
}

View File

@@ -1,27 +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.idea.refactoring.changeSignature;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.util.TextOccurrencesUtil;
import com.intellij.usageView.UsageInfo;
import java.util.Collection;
// FIX ME WHEN BUNCH 201 REMOVED
final class BunchedDeprecation {
public static void findNonCodeUsages(
PsiElement element,
String stringToSearch,
boolean searchInStringsAndComments,
boolean searchInNonJavaFiles,
String newQName,
Collection<? super UsageInfo> results) {
TextOccurrencesUtil.findNonCodeUsages(element, GlobalSearchScope.projectScope(element.getProject()),
stringToSearch, searchInStringsAndComments, searchInNonJavaFiles, newQName, results);
}
}

View File

@@ -10,6 +10,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Ref
import com.intellij.psi.*
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.MethodReferencesSearch
import com.intellij.psi.search.searches.OverridingMethodsSearch
import com.intellij.psi.search.searches.ReferencesSearch
@@ -20,6 +21,7 @@ import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo
import com.intellij.refactoring.util.CommonRefactoringUtil
import com.intellij.refactoring.util.MoveRenameUsageInfo
import com.intellij.refactoring.util.RefactoringUIUtil
import com.intellij.refactoring.util.TextOccurrencesUtil
import com.intellij.usageView.UsageInfo
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
@@ -269,7 +271,10 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
val oldName = changeInfo.oldName
if (oldName != null) {
BunchedDeprecation.findNonCodeUsages(functionPsi, oldName, true, true, changeInfo.newName, result)
TextOccurrencesUtil.findNonCodeUsages(
functionPsi, GlobalSearchScope.projectScope(functionPsi.project),
oldName, true, true, changeInfo.newName, result
)
}
val oldParameters = (functionPsi as KtNamedDeclaration).getValueParameters()

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2010-2019 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.idea.refactoring.changeSignature
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
class KotlinMutableMethodDescriptor(override val original: KotlinMethodDescriptor) : KotlinMethodDescriptor by original {
private val parameters: MutableList<KotlinParameterInfo> = original.parameters
override var receiver: KotlinParameterInfo? = original.receiver
set(value: KotlinParameterInfo?) {
if (value != null && value !in parameters) {
parameters.add(value)
}
field = value
}
fun addParameter(parameter: KotlinParameterInfo) {
parameters.add(parameter)
}
fun addParameter(index: Int, parameter: KotlinParameterInfo) {
parameters.add(index, parameter)
}
fun removeParameter(index: Int) {
val paramInfo = parameters.removeAt(index)
if (paramInfo == receiver) {
receiver = null
}
}
fun renameParameter(index: Int, newName: String) {
parameters[index].name = newName
}
fun clearNonReceiverParameters() {
parameters.clear()
receiver?.let { parameters.add(it) }
}
override fun getVisibility(): DescriptorVisibility {
return original.visibility
}
}

View File

@@ -1,27 +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.idea.refactoring.move.moveDeclarations;
import com.intellij.psi.PsiElement;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.refactoring.util.TextOccurrencesUtil;
import com.intellij.usageView.UsageInfo;
import java.util.Collection;
// FIX ME WHEN BUNCH 201 REMOVED
final class BunchedDeprecation {
public static void findNonCodeUsages(
PsiElement element,
String stringToSearch,
boolean searchInStringsAndComments,
boolean searchInNonJavaFiles,
String newQName,
Collection<? super UsageInfo> results) {
TextOccurrencesUtil.findNonCodeUsages(element, GlobalSearchScope.projectScope(element.getProject()),
stringToSearch, searchInStringsAndComments, searchInNonJavaFiles, newQName, results);
}
}

View File

@@ -22,6 +22,7 @@ import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassHandler
import com.intellij.refactoring.rename.RenameUtil
import com.intellij.refactoring.util.NonCodeUsageInfo
import com.intellij.refactoring.util.RefactoringUIUtil
import com.intellij.refactoring.util.TextOccurrencesUtil
import com.intellij.usageView.UsageInfo
import com.intellij.usageView.UsageViewBundle
import com.intellij.usageView.UsageViewDescriptor
@@ -224,8 +225,9 @@ class MoveKotlinDeclarationsProcessor(
val name = lightElement.getKotlinFqName()?.quoteIfNeeded()?.asString()
if (name != null) {
fun searchForKotlinNameUsages(results: ArrayList<UsageInfo>) {
BunchedDeprecation.findNonCodeUsages(
TextOccurrencesUtil.findNonCodeUsages(
lightElement,
GlobalSearchScope.projectScope(lightElement.project),
name,
descriptor.searchInCommentsAndStrings,
descriptor.searchInNonCode,
@@ -242,8 +244,9 @@ class MoveKotlinDeclarationsProcessor(
elementName
)
BunchedDeprecation.findNonCodeUsages(
TextOccurrencesUtil.findNonCodeUsages(
lightElement,
GlobalSearchScope.projectScope(lightElement.project),
oldFqNameWithFacade,
descriptor.searchInCommentsAndStrings,
descriptor.searchInNonCode,

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2010-2019 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.idea.reporter
import com.intellij.diagnostic.ITNReporter
import com.intellij.openapi.diagnostic.IdeaLoggingEvent
import com.intellij.openapi.diagnostic.SubmittedReportInfo
import com.intellij.util.Consumer
import java.awt.Component
abstract class ITNReporterCompat : ITNReporter() {
final override fun submit(
events: Array<IdeaLoggingEvent>,
additionalInfo: String?,
parentComponent: Component?,
consumer: Consumer<SubmittedReportInfo>
): Boolean {
return submitCompat(events, additionalInfo, parentComponent, consumer)
}
open fun submitCompat(
events: Array<IdeaLoggingEvent>,
additionalInfo: String?,
parentComponent: Component?,
consumer: Consumer<SubmittedReportInfo>
): Boolean {
@Suppress("IncompatibleAPI")
return super.submit(events, additionalInfo, parentComponent, consumer)
}
}

View File

@@ -1,111 +0,0 @@
/*
* Copyright 2010-2019 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.idea.search.ideaExtensions
import com.intellij.codeInsight.JavaTargetElementEvaluator
import com.intellij.codeInsight.TargetElementEvaluatorEx
import com.intellij.codeInsight.TargetElementUtil
import com.intellij.codeInsight.TargetElementUtilExtender
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiReference
import com.intellij.util.BitUtil
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.idea.intentions.isAutoCreatedItUsage
import org.jetbrains.kotlin.idea.references.KtDestructuringDeclarationReference
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.source.getPsi
class KotlinTargetElementEvaluator : TargetElementEvaluatorEx, TargetElementUtilExtender {
companion object {
const val DO_NOT_UNWRAP_LABELED_EXPRESSION = 0x100
const val BYPASS_IMPORT_ALIAS = 0x200
// Place caret after the open curly brace in lambda for generated 'it'
fun findLambdaOpenLBraceForGeneratedIt(ref: PsiReference): PsiElement? {
val element: PsiElement = ref.element
if (element.text != "it") return null
if (element !is KtNameReferenceExpression || !isAutoCreatedItUsage(element)) return null
val itDescriptor = element.resolveMainReferenceToDescriptors().singleOrNull() ?: return null
val descriptorWithSource = itDescriptor.containingDeclaration as? DeclarationDescriptorWithSource ?: return null
val lambdaExpression = descriptorWithSource.source.getPsi()?.parent as? KtLambdaExpression ?: return null
return lambdaExpression.leftCurlyBrace.treeNext?.psi
}
// Navigate to receiver element for this in extension declaration
fun findReceiverForThisInExtensionFunction(ref: PsiReference): PsiElement? {
val element: PsiElement = ref.element
if (element.text != "this") return null
if (element !is KtNameReferenceExpression) return null
val callableDescriptor = element.resolveMainReferenceToDescriptors().singleOrNull() as? CallableDescriptor ?: return null
if (!callableDescriptor.isExtension) return null
val callableDeclaration = callableDescriptor.source.getPsi() as? KtCallableDeclaration ?: return null
return callableDeclaration.receiverTypeReference
}
}
override fun getAdditionalDefinitionSearchFlags() = 0
override fun getAdditionalReferenceSearchFlags() = DO_NOT_UNWRAP_LABELED_EXPRESSION or BYPASS_IMPORT_ALIAS
override fun getAllAdditionalFlags() = additionalDefinitionSearchFlags + additionalReferenceSearchFlags
override fun includeSelfInGotoImplementation(element: PsiElement): Boolean = !(element is KtClass && element.isAbstract())
override fun getElementByReference(ref: PsiReference, flags: Int): PsiElement? {
if (ref is KtSimpleNameReference && ref.expression is KtLabelReferenceExpression) {
val refTarget = ref.resolve() as? KtExpression ?: return null
if (!BitUtil.isSet(flags, DO_NOT_UNWRAP_LABELED_EXPRESSION)) {
return refTarget.getLabeledParent(ref.expression.getReferencedName()) ?: refTarget
}
return refTarget
}
if (!BitUtil.isSet(flags, BYPASS_IMPORT_ALIAS)) {
(ref.element as? KtSimpleNameExpression)?.mainReference?.getImportAlias()?.let { return it }
}
// prefer destructing declaration entry to its target if element name is accepted
if (ref is KtDestructuringDeclarationReference && BitUtil.isSet(flags, TargetElementUtil.ELEMENT_NAME_ACCEPTED)) {
return ref.element
}
val refExpression = ref.element as? KtSimpleNameExpression
val calleeExpression = refExpression?.getParentOfTypeAndBranch<KtCallElement> { calleeExpression }
if (calleeExpression != null) {
(ref.resolve() as? KtConstructor<*>)?.let {
return if (flags and JavaTargetElementEvaluator().additionalReferenceSearchFlags != 0) it else it.containingClassOrObject
}
}
if (BitUtil.isSet(flags, TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED)) {
return findLambdaOpenLBraceForGeneratedIt(ref)
?: findReceiverForThisInExtensionFunction(ref)
}
return null
}
override fun isIdentifierPart(file: PsiFile, text: CharSequence?, offset: Int): Boolean {
val elementAtCaret = file.findElementAt(offset)
if (elementAtCaret?.node?.elementType == KtTokens.IDENTIFIER) return true
// '(' is considered identifier part if it belongs to primary constructor without 'constructor' keyword
return elementAtCaret?.getNonStrictParentOfType<KtPrimaryConstructor>()?.textOffset == offset
}
}

View File

@@ -1,127 +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.idea.slicer
import com.intellij.codeInsight.Nullability
import com.intellij.ide.util.treeView.AbstractTreeStructure
import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.psi.PsiElement
import com.intellij.psi.util.parentOfType
import com.intellij.slicer.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isPlainWithEscapes
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi2ir.deparenthesize
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.isNullabilityFlexible
class KotlinSliceProvider : SliceLanguageSupportProvider, SliceUsageTransformer {
companion object {
val LEAF_ELEMENT_EQUALITY = object : SliceLeafEquality() {
override fun substituteElement(element: PsiElement) = (element as? KtReference)?.resolve() ?: element
}
}
class KotlinGroupByNullnessAction(treeBuilder: SliceTreeBuilder) : GroupByNullnessActionBase(treeBuilder) {
override fun isAvailable() = true
}
val leafAnalyzer by lazy { SliceLeafAnalyzer(LEAF_ELEMENT_EQUALITY, this) }
val nullnessAnalyzer: HackedSliceNullnessAnalyzerBase by lazy {
object : HackedSliceNullnessAnalyzerBase(LEAF_ELEMENT_EQUALITY, this) {
override fun checkNullability(element: PsiElement?): Nullability {
val types = when (element) {
is KtCallableDeclaration -> listOfNotNull((element.resolveToDescriptorIfAny() as? CallableDescriptor)?.returnType)
is KtDeclaration -> emptyList()
is KtExpression -> listOfNotNull(element.analyze(BodyResolveMode.PARTIAL).getType(element))
else -> emptyList()
}
return when {
types.isEmpty() -> return Nullability.UNKNOWN
types.all { KotlinBuiltIns.isNullableNothing(it) } -> Nullability.NULLABLE
types.any { it.isError || TypeUtils.isNullableType(it) || it.isNullabilityFlexible() } -> Nullability.UNKNOWN
else -> Nullability.NOT_NULL
}
}
}
}
override fun createRootUsage(element: PsiElement, params: SliceAnalysisParams) = KotlinSliceUsage(element, params)
override fun transform(usage: SliceUsage): Collection<SliceUsage>? {
if (usage is KotlinSliceUsage) return null
return listOf(KotlinSliceUsage(usage.element, usage.parent, KotlinSliceAnalysisMode.Default, false))
}
override fun getExpressionAtCaret(atCaret: PsiElement, dataFlowToThis: Boolean): KtElement? {
val element = atCaret.parentsWithSelf
.filterIsInstance<KtElement>()
.firstOrNull(::isSliceElement)
?.deparenthesize() ?: return null
if (dataFlowToThis) {
if (element is KtConstantExpression) return null
if (element is KtStringTemplateExpression && element.isPlainWithEscapes()) return null
if (element is KtClassLiteralExpression) return null
if (element is KtCallableReferenceExpression) return null
}
return element
}
private fun isSliceElement(element: KtElement): Boolean {
return when {
element is KtProperty -> true
element is KtParameter -> true
element is KtDeclarationWithBody -> true
element is KtClass && !element.hasExplicitPrimaryConstructor() -> true
element is KtExpression && element !is KtDeclaration && element.parentOfType<KtTypeReference>() == null -> true
element is KtTypeReference && element == (element.parent as? KtCallableDeclaration)?.receiverTypeReference -> true
else -> false
}
}
override fun getElementForDescription(element: PsiElement): PsiElement {
return (element as? KtSimpleNameExpression)?.mainReference?.resolve() ?: element
}
override fun getRenderer() = KotlinSliceUsageCellRenderer
override fun startAnalyzeLeafValues(structure: AbstractTreeStructure, finalRunnable: Runnable) {
leafAnalyzer.startAnalyzeValues(structure, finalRunnable)
}
override fun startAnalyzeNullness(structure: AbstractTreeStructure, finalRunnable: Runnable) {
nullnessAnalyzer.startAnalyzeNullness(structure, finalRunnable)
}
override fun registerExtraPanelActions(group: DefaultActionGroup, builder: SliceTreeBuilder) {
if (builder.dataFlowToThis) {
group.add(GroupByLeavesAction(builder))
group.add(KotlinGroupByNullnessAction(builder))
}
}
}

View File

@@ -14,7 +14,6 @@ import com.intellij.psi.search.GlobalSearchScope
import com.intellij.util.concurrency.AppExecutorUtil
import java.util.concurrent.Callable
// FIX ME WHEN BUNCH 201 REMOVED
fun runActivity(project: Project) {
nonBlocking(Callable {

View File

@@ -1,11 +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.idea
// Remove the function, when there's no dependency to cidr during running Kotlin tests.
// FIX ME WHEN BUNCH as41 REMOVED
fun registerAdditionalResourceBundleInTests() {
}

View File

@@ -1,31 +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.
*/
@file:Suppress("DEPRECATION")
package org.jetbrains.kotlin.idea
import com.intellij.featureStatistics.FeatureStatisticsBundleEP
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.extensions.Extensions
import com.jetbrains.cidr.lang.OCBundle
// Remove the function, when there's no dependency to cidr during running Kotlin tests.
fun registerAdditionalResourceBundleInTests() {
if (!ApplicationManager.getApplication().isUnitTestMode) {
return
}
val extensionPoint = Extensions.getRootArea().getExtensionPoint(FeatureStatisticsBundleEP.EP_NAME)
if (extensionPoint.extensions.none { it.qualifiedName == TestOCBundleProvider.qualifiedName }) {
extensionPoint.registerExtension(TestOCBundleProvider)
}
}
object TestOCBundleProvider : FeatureStatisticsBundleEP() {
init {
qualifiedName = OCBundle.BUNDLE
}
}

View File

@@ -1,12 +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.
*/
@file:Suppress("DEPRECATION")
package org.jetbrains.kotlin.idea
// Remove the function, when there's no dependency to cidr during running Kotlin tests.
fun registerAdditionalResourceBundleInTests() {
}

View File

@@ -1,157 +0,0 @@
/*
* Copyright 2010-2019 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.idea.update
import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.ide.plugins.PluginNode
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.util.isDev
import org.jetbrains.kotlin.idea.util.isEap
import java.io.IOException
import java.net.URL
import java.util.*
import javax.xml.bind.JAXBContext
import javax.xml.bind.JAXBException
import javax.xml.bind.annotation.*
class GooglePluginUpdateVerifier : PluginUpdateVerifier() {
override val verifierName: String
get() = KotlinBundle.message("update.name.android.studio")
// Verifies if a plugin can be installed in Android Studio 3.2+.
// Currently used only by KotlinPluginUpdater.
override fun verify(pluginDescriptor: IdeaPluginDescriptor): PluginVerifyResult? {
if (pluginDescriptor.pluginId.idString != KOTLIN_PLUGIN_ID) {
return null
}
val version = pluginDescriptor.version
if (isEap(version) || isDev(version)) {
return PluginVerifyResult.accept()
}
try {
val url = URL(METADATA_FILE_URL)
val stream = url.openStream()
val context = JAXBContext.newInstance(PluginCompatibility::class.java)
val unmarshaller = context.createUnmarshaller()
val pluginCompatibility = unmarshaller.unmarshal(stream) as PluginCompatibility
val release = getRelease(pluginCompatibility)
?: return PluginVerifyResult.decline(KotlinBundle.message("update.reason.text.no.verified.versions.for.this.build"))
return if (release.plugins().any { KOTLIN_PLUGIN_ID == it.id && version == it.version })
PluginVerifyResult.accept()
else
PluginVerifyResult.decline(KotlinBundle.message("update.reason.text.version.to.be.verified"))
} catch (e: Exception) {
LOG.info("Exception when verifying plugin ${pluginDescriptor.pluginId.idString} version $version", e)
return when (e) {
is IOException ->
PluginVerifyResult.decline(KotlinBundle.message("update.reason.text.unable.to.connect.to.compatibility.verification.repository"))
is JAXBException -> PluginVerifyResult.decline(KotlinBundle.message("update.reason.text.unable.to.parse.compatibility.verification.metadata"))
else -> PluginVerifyResult.decline(
KotlinBundle.message("update.reason.text.exception.during.verification",
e.message.toString()
)
)
}
}
}
private fun getRelease(pluginCompatibility: PluginCompatibility): StudioRelease? {
for (studioRelease in pluginCompatibility.releases()) {
if (buildInRange(studioRelease.name, studioRelease.sinceBuild, studioRelease.untilBuild)) {
return studioRelease
}
}
return null
}
private fun buildInRange(name: String?, sinceBuild: String?, untilBuild: String?): Boolean {
val descriptor = PluginNode()
descriptor.name = name
descriptor.sinceBuild = sinceBuild
descriptor.untilBuild = untilBuild
return PluginManagerCore.isCompatible(descriptor)
}
companion object {
private const val KOTLIN_PLUGIN_ID = "org.jetbrains.kotlin"
private const val METADATA_FILE_URL = "https://dl.google.com/android/studio/plugins/compatibility.xml"
private val LOG = Logger.getInstance(GooglePluginUpdateVerifier::class.java)
private fun PluginCompatibility.releases() = studioRelease ?: emptyArray()
private fun StudioRelease.plugins() = ideaPlugin ?: emptyArray()
@XmlRootElement(name = "plugin-compatibility")
@XmlAccessorType(XmlAccessType.FIELD)
class PluginCompatibility {
@XmlElement(name = "studio-release")
var studioRelease: Array<StudioRelease>? = null
override fun toString(): String {
return "PluginCompatibility(studioRelease=${Arrays.toString(studioRelease)})"
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class StudioRelease {
@XmlAttribute(name = "until-build")
var untilBuild: String? = null
@XmlAttribute(name = "since-build")
var sinceBuild: String? = null
@XmlAttribute
var name: String? = null
@XmlAttribute
var channel: String? = null
@XmlElement(name = "idea-plugin")
var ideaPlugin: Array<IdeaPlugin>? = null
override fun toString(): String {
return "StudioRelease(" +
"untilBuild=$untilBuild, name=$name, ideaPlugin=${Arrays.toString(ideaPlugin)}, " +
"sinceBuild=$sinceBuild, channel=$channel" +
")"
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class IdeaPlugin {
@XmlAttribute
var id: String? = null
@XmlAttribute
var sha256: String? = null
@XmlAttribute
var channel: String? = null
@XmlAttribute
var version: String? = null
@XmlElement(name = "idea-version")
var ideaVersion: IdeaVersion? = null
override fun toString(): String {
return "IdeaPlugin(id=$id, sha256=$sha256, ideaVersion=$ideaVersion, channel=$channel, version=$version)"
}
}
@XmlAccessorType(XmlAccessType.FIELD)
class IdeaVersion {
@XmlAttribute(name = "until-build")
var untilBuild: String? = null
@XmlAttribute(name = "since-build")
var sinceBuild: String? = null
override fun toString(): String {
return "IdeaVersion(untilBuild=$untilBuild, sinceBuild=$sinceBuild)"
}
}
}
}

View File

@@ -1,35 +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.idea.update
import com.intellij.ide.plugins.IdeaPluginDescriptor
import com.intellij.openapi.util.registry.Registry
import org.jetbrains.kotlin.idea.PluginUpdateStatus
// Do an additional verification with PluginUpdateVerifier. Enabled only in AS 3.2+
fun verify(updateStatus: PluginUpdateStatus.Update): PluginUpdateStatus {
@Suppress("InvalidBundleOrProperty")
val pluginVerifierEnabled = Registry.`is`("kotlin.plugin.update.verifier.enabled", true)
if (!pluginVerifierEnabled) {
return updateStatus
}
val pluginDescriptor: IdeaPluginDescriptor = updateStatus.pluginDescriptor
val pluginVerifiers = PluginUpdateVerifier.EP_NAME.extensions
for (pluginVerifier in pluginVerifiers) {
val verifyResult = pluginVerifier.verify(pluginDescriptor) ?: continue
if (!verifyResult.verified) {
return PluginUpdateStatus.Unverified(
pluginVerifier.verifierName,
verifyResult.declineMessage,
updateStatus
)
}
}
return updateStatus
}

View File

@@ -1,7 +0,0 @@
import org.junit.Test
class <lineMarker descr="Run Test" settings="Nothing here">MyKotlinTest</lineMarker> {
@Test
fun <lineMarker descr="Run Test" settings="Nothing here">testA</lineMarker>() {
}
}

View File

@@ -1,11 +0,0 @@
import org.junit.Test
class <lineMarker descr="Run Test" settings="Nothing here">MyKotlinTest</lineMarker> {
@Test
fun <lineMarker descr="Run Test" settings="Nothing here">testA</lineMarker>() {
}
@Test
fun <lineMarker descr="Run Test" settings="Nothing here">testB</lineMarker>() {
}
}

View File

@@ -1,7 +0,0 @@
// "Add 'int' as 1st parameter to method 'K'" "true"
public class J {
void foo() {
new K(1);
}
}

View File

@@ -1,7 +0,0 @@
// "Add 'int' as 1st parameter to method 'K'" "true"
public class J {
void foo() {
new K(<caret>1);
}
}

View File

@@ -1,7 +0,0 @@
// "Add 'int' as 1st parameter to method 'K'" "true"
public class J {
void foo() {
new K(1);
}
}

View File

@@ -1,7 +0,0 @@
// "Add 'int' as 1st parameter to method 'K'" "true"
public class J {
void foo() {
new K(<caret>1);
}
}

View File

@@ -1,7 +0,0 @@
// "Add 'int' as 1st parameter to method 'K'" "true"
public class J {
void foo() {
new K(1);
}
}

View File

@@ -1,7 +0,0 @@
// "Add 'int' as 1st parameter to method 'K'" "true"
public class J {
void foo() {
new K(<caret>1);
}
}

View File

@@ -1,7 +0,0 @@
// "Change 2nd parameter of method 'K' from 'boolean' to 'String'" "true"
public class J {
void foo() {
new K(1, <caret>"2");
}
}

View File

@@ -1,7 +0,0 @@
// "Change 2nd parameter of method 'K' from 'boolean' to 'String'" "true"
public class J {
void foo() {
new K(1, <caret>"2");
}
}

View File

@@ -1,7 +0,0 @@
// "Change 2nd parameter of method 'K' from 'boolean' to 'String'" "true"
public class J {
void foo() {
new K(1, <caret>"2");
}
}

View File

@@ -1,7 +0,0 @@
// "Change 2nd parameter of method 'K' from 'boolean' to 'String'" "true"
public class J {
void foo() {
new K(1, <caret>"2");
}
}

View File

@@ -1,7 +0,0 @@
// "Add 'int' as 1st parameter to method 'Foo'" "true"
public class J {
void test() {
new Foo(<caret>1, 2);
}
}

View File

@@ -1,7 +0,0 @@
// "Add 'int' as 1st parameter to method 'Foo'" "true"
public class J {
void test() {
new Foo(<caret>1, 2);
}
}

View File

@@ -1,7 +0,0 @@
// "Add 'int' as 2nd parameter to method 'Foo'" "true"
public class J {
void test() {
new Foo(<caret>1, 2);
}
}

Some files were not shown because too many files have changed in this diff Show More