Cleanup 201 and as41 bunch files
This commit is contained in:
-13
@@ -1,13 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
|
||||||
|
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
|
||||||
|
|
||||||
// This object should help compiling against different ASM versions from different bunch versions
|
|
||||||
object VersionIndependentOpcodes {
|
|
||||||
const val ACC_RECORD = 0
|
|
||||||
}
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen;
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.FileMapping;
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.SMAPBuilder;
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
|
||||||
import org.jetbrains.org.objectweb.asm.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
|
|
||||||
|
|
||||||
public abstract class AbstractClassBuilder implements ClassBuilder {
|
|
||||||
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.API_VERSION) {};
|
|
||||||
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.API_VERSION) {};
|
|
||||||
|
|
||||||
private String thisName;
|
|
||||||
|
|
||||||
private final JvmSerializationBindings serializationBindings = new JvmSerializationBindings();
|
|
||||||
|
|
||||||
private String sourceName;
|
|
||||||
|
|
||||||
private String debugInfo;
|
|
||||||
|
|
||||||
public static class Concrete extends AbstractClassBuilder {
|
|
||||||
private final ClassVisitor v;
|
|
||||||
|
|
||||||
public Concrete(@NotNull ClassVisitor v) {
|
|
||||||
this.v = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public ClassVisitor getVisitor() {
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public FieldVisitor newField(
|
|
||||||
@NotNull JvmDeclarationOrigin origin,
|
|
||||||
int access,
|
|
||||||
@NotNull String name,
|
|
||||||
@NotNull String desc,
|
|
||||||
@Nullable String signature,
|
|
||||||
@Nullable Object value
|
|
||||||
) {
|
|
||||||
FieldVisitor visitor = getVisitor().visitField(access, name, desc, signature, value);
|
|
||||||
if (visitor == null) {
|
|
||||||
return EMPTY_FIELD_VISITOR;
|
|
||||||
}
|
|
||||||
return visitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public MethodVisitor newMethod(
|
|
||||||
@NotNull JvmDeclarationOrigin origin,
|
|
||||||
int access,
|
|
||||||
@NotNull String name,
|
|
||||||
@NotNull String desc,
|
|
||||||
@Nullable String signature,
|
|
||||||
@Nullable String[] exceptions
|
|
||||||
) {
|
|
||||||
MethodVisitor visitor = getVisitor().visitMethod(access, name, desc, signature, exceptions);
|
|
||||||
if (visitor == null) {
|
|
||||||
return EMPTY_METHOD_VISITOR;
|
|
||||||
}
|
|
||||||
return visitor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public JvmSerializationBindings getSerializationBindings() {
|
|
||||||
return serializationBindings;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
|
|
||||||
return getVisitor().visitAnnotation(desc, visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void done() {
|
|
||||||
getVisitor().visitSource(sourceName, debugInfo);
|
|
||||||
getVisitor().visitEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void defineClass(
|
|
||||||
@Nullable PsiElement origin,
|
|
||||||
int version,
|
|
||||||
int access,
|
|
||||||
@NotNull String name,
|
|
||||||
@Nullable String signature,
|
|
||||||
@NotNull String superName,
|
|
||||||
@NotNull String[] interfaces
|
|
||||||
) {
|
|
||||||
thisName = name;
|
|
||||||
getVisitor().visit(version, access, name, signature, superName, interfaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitSource(@NotNull String name, @Nullable String debug) {
|
|
||||||
assert sourceName == null || sourceName.equals(name) : "inconsistent file name: " + sourceName + " vs " + name;
|
|
||||||
sourceName = name;
|
|
||||||
debugInfo = debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax) {
|
|
||||||
if (!GENERATE_SMAP) return;
|
|
||||||
|
|
||||||
List<FileMapping> fileMappings = smap.getResultMappings();
|
|
||||||
if (fileMappings.isEmpty()) return;
|
|
||||||
|
|
||||||
visitSource(fileMappings.get(0).getName(), SMAPBuilder.INSTANCE.build(fileMappings, backwardsCompatibleSyntax));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
|
|
||||||
getVisitor().visitOuterClass(owner, name, desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
|
|
||||||
getVisitor().visitInnerClass(name, outerName, innerName, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String getThisName() {
|
|
||||||
assert thisName != null : "This name isn't set";
|
|
||||||
return thisName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen;
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
|
||||||
import org.jetbrains.org.objectweb.asm.*;
|
|
||||||
|
|
||||||
public interface ClassBuilder {
|
|
||||||
@NotNull
|
|
||||||
FieldVisitor newField(
|
|
||||||
@NotNull JvmDeclarationOrigin origin,
|
|
||||||
int access,
|
|
||||||
@NotNull String name,
|
|
||||||
@NotNull String desc,
|
|
||||||
@Nullable String signature,
|
|
||||||
@Nullable Object value
|
|
||||||
);
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
MethodVisitor newMethod(
|
|
||||||
@NotNull JvmDeclarationOrigin origin,
|
|
||||||
int access,
|
|
||||||
@NotNull String name,
|
|
||||||
@NotNull String desc,
|
|
||||||
@Nullable String signature,
|
|
||||||
@Nullable String[] exceptions
|
|
||||||
);
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
JvmSerializationBindings getSerializationBindings();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible);
|
|
||||||
|
|
||||||
void done();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
ClassVisitor getVisitor();
|
|
||||||
|
|
||||||
void defineClass(
|
|
||||||
@Nullable PsiElement origin,
|
|
||||||
int version,
|
|
||||||
int access,
|
|
||||||
@NotNull String name,
|
|
||||||
@Nullable String signature,
|
|
||||||
@NotNull String superName,
|
|
||||||
@NotNull String[] interfaces
|
|
||||||
);
|
|
||||||
|
|
||||||
void visitSource(@NotNull String name, @Nullable String debug);
|
|
||||||
|
|
||||||
void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax);
|
|
||||||
|
|
||||||
void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc);
|
|
||||||
|
|
||||||
void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access);
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
String getThisName();
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER", "unused")
|
|
||||||
fun ClassBuilder.addRecordComponent(name: String, desc: String, signature: String?) {
|
|
||||||
// newRecordComponent(name, desc, signature)
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen;
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
|
||||||
import org.jetbrains.org.objectweb.asm.*;
|
|
||||||
|
|
||||||
public abstract class DelegatingClassBuilder implements ClassBuilder {
|
|
||||||
@NotNull
|
|
||||||
protected abstract ClassBuilder getDelegate();
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public FieldVisitor newField(
|
|
||||||
@NotNull JvmDeclarationOrigin origin,
|
|
||||||
int access,
|
|
||||||
@NotNull String name,
|
|
||||||
@NotNull String desc,
|
|
||||||
@Nullable String signature,
|
|
||||||
@Nullable Object value
|
|
||||||
) {
|
|
||||||
return getDelegate().newField(origin, access, name, desc, signature, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public MethodVisitor newMethod(
|
|
||||||
@NotNull JvmDeclarationOrigin origin,
|
|
||||||
int access,
|
|
||||||
@NotNull String name,
|
|
||||||
@NotNull String desc,
|
|
||||||
@Nullable String signature,
|
|
||||||
@Nullable String[] exceptions
|
|
||||||
) {
|
|
||||||
return getDelegate().newMethod(origin, access, name, desc, signature, exceptions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public JvmSerializationBindings getSerializationBindings() {
|
|
||||||
return getDelegate().getSerializationBindings();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
|
|
||||||
return getDelegate().newAnnotation(desc, visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void done() {
|
|
||||||
getDelegate().done();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public ClassVisitor getVisitor() {
|
|
||||||
return getDelegate().getVisitor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void defineClass(
|
|
||||||
@Nullable PsiElement origin,
|
|
||||||
int version,
|
|
||||||
int access,
|
|
||||||
@NotNull String name,
|
|
||||||
@Nullable String signature,
|
|
||||||
@NotNull String superName,
|
|
||||||
@NotNull String[] interfaces
|
|
||||||
) {
|
|
||||||
getDelegate().defineClass(origin, version, access, name, signature, superName, interfaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitSource(@NotNull String name, @Nullable String debug) {
|
|
||||||
getDelegate().visitSource(name, debug);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax) {
|
|
||||||
getDelegate().visitSMAP(smap, backwardsCompatibleSyntax);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
|
|
||||||
getDelegate().visitOuterClass(owner, name, desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
|
|
||||||
getDelegate().visitInnerClass(name, outerName, innerName, access);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getThisName() {
|
|
||||||
return getDelegate().getThisName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-11
@@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.optimization.common
|
|
||||||
|
|
||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
|
||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
|
||||||
|
|
||||||
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.state
|
|
||||||
|
|
||||||
typealias JvmMethodExceptionTypes = Array<out String>?
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension
|
|
||||||
import com.intellij.pom.java.LanguageLevel
|
|
||||||
|
|
||||||
fun Project.setupHighestLanguageLevel() {
|
|
||||||
// LanguageLevelProjectExtension.getInstance(this).languageLevel = LanguageLevel.JDK_15_PREVIEW
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
|
||||||
|
|
||||||
fun setupIdeaStandaloneExecution() {
|
|
||||||
System.getProperties().setProperty("idea.plugins.compatible.build", "201.6668.13")
|
|
||||||
System.getProperties().setProperty("project.structure.add.tools.jar.to.new.jdk", "false")
|
|
||||||
System.getProperties().setProperty("psi.track.invalidation", "true")
|
|
||||||
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
|
||||||
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
|
||||||
System.getProperties().setProperty("ast.loading.filter", "false")
|
|
||||||
}
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.asJava.classes
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.augment.PsiAugmentProvider
|
|
||||||
|
|
||||||
internal fun <Psi : PsiElement> collectAugments(element: PsiElement, type: Class<out Psi>): List<Psi> {
|
|
||||||
return PsiAugmentProvider.collectAugments(element, type)
|
|
||||||
}
|
|
||||||
-154
@@ -1,154 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.load.java.structure.impl
|
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.psi.PsiClass
|
|
||||||
import com.intellij.psi.PsiTypeParameter
|
|
||||||
import com.intellij.psi.search.SearchScope
|
|
||||||
import org.jetbrains.kotlin.asJava.KtLightClassMarker
|
|
||||||
import org.jetbrains.kotlin.asJava.isSyntheticValuesOrValueOfMethod
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.*
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
|
||||||
|
|
||||||
class JavaClassImpl(psiClass: PsiClass) : JavaClassifierImpl<PsiClass>(psiClass), VirtualFileBoundJavaClass, JavaAnnotationOwnerImpl, JavaModifierListOwnerImpl {
|
|
||||||
init {
|
|
||||||
assert(psiClass !is PsiTypeParameter) { "PsiTypeParameter should be wrapped in JavaTypeParameter, not JavaClass: use JavaClassifier.create()" }
|
|
||||||
}
|
|
||||||
|
|
||||||
override val innerClassNames: Collection<Name>
|
|
||||||
get() = psi.innerClasses.mapNotNull { it.name?.takeIf(Name::isValidIdentifier)?.let(Name::identifier) }
|
|
||||||
|
|
||||||
override fun findInnerClass(name: Name): JavaClass? {
|
|
||||||
return psi.findInnerClassByName(name.asString(), false)?.let(::JavaClassImpl)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val fqName: FqName?
|
|
||||||
get() {
|
|
||||||
val qualifiedName = psi.qualifiedName
|
|
||||||
return if (qualifiedName == null) null else FqName(qualifiedName)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val name: Name
|
|
||||||
get() = KtPsiUtil.safeName(psi.name)
|
|
||||||
|
|
||||||
override val isInterface: Boolean
|
|
||||||
get() = psi.isInterface
|
|
||||||
|
|
||||||
override val isAnnotationType: Boolean
|
|
||||||
get() = psi.isAnnotationType
|
|
||||||
|
|
||||||
override val isEnum: Boolean
|
|
||||||
get() = psi.isEnum
|
|
||||||
|
|
||||||
override val isRecord: Boolean
|
|
||||||
get() = false
|
|
||||||
|
|
||||||
override val isSealed: Boolean
|
|
||||||
get() = JavaElementUtil.isSealed(this)
|
|
||||||
|
|
||||||
override val permittedTypes: Collection<JavaClassifierType>
|
|
||||||
get() = emptyList()
|
|
||||||
|
|
||||||
override val outerClass: JavaClassImpl?
|
|
||||||
get() {
|
|
||||||
val outer = psi.containingClass
|
|
||||||
return if (outer == null) null else JavaClassImpl(outer)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val typeParameters: List<JavaTypeParameter>
|
|
||||||
get() = typeParameters(psi.typeParameters)
|
|
||||||
|
|
||||||
override val supertypes: Collection<JavaClassifierType>
|
|
||||||
get() = classifierTypes(psi.superTypes)
|
|
||||||
|
|
||||||
override val methods: Collection<JavaMethod>
|
|
||||||
get() {
|
|
||||||
assertNotLightClass()
|
|
||||||
// We apply distinct here because PsiClass#getMethods() can return duplicate PSI methods, for example in Lombok (see KT-11778)
|
|
||||||
// Return type seems to be null for example for the 'clone' Groovy method generated by @AutoClone (see EA-73795)
|
|
||||||
return methods(
|
|
||||||
psi.methods.filter { method ->
|
|
||||||
!method.isConstructor && method.returnType != null && !(isEnum && isSyntheticValuesOrValueOfMethod(method))
|
|
||||||
}
|
|
||||||
).distinct()
|
|
||||||
}
|
|
||||||
|
|
||||||
override val fields: Collection<JavaField>
|
|
||||||
get() {
|
|
||||||
assertNotLightClass()
|
|
||||||
return fields(psi.fields.filter {
|
|
||||||
// ex. Android plugin generates LightFields for resources started from '.' (.DS_Store file etc)
|
|
||||||
Name.isValidIdentifier(it.name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override val constructors: Collection<JavaConstructor>
|
|
||||||
get() {
|
|
||||||
assertNotLightClass()
|
|
||||||
// See for example org.jetbrains.plugins.scala.lang.psi.light.ScFunctionWrapper,
|
|
||||||
// which is present in getConstructors(), but its isConstructor() returns false
|
|
||||||
return constructors(psi.constructors.filter { method -> method.isConstructor })
|
|
||||||
}
|
|
||||||
|
|
||||||
override val recordComponents: Collection<JavaRecordComponent>
|
|
||||||
get() {
|
|
||||||
assertNotLightClass()
|
|
||||||
|
|
||||||
return emptyList<JavaRecordComponent>()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hasDefaultConstructor() = !isInterface && constructors.isEmpty()
|
|
||||||
|
|
||||||
override val isAbstract: Boolean
|
|
||||||
get() = JavaElementUtil.isAbstract(this)
|
|
||||||
|
|
||||||
override val isStatic: Boolean
|
|
||||||
get() = JavaElementUtil.isStatic(this)
|
|
||||||
|
|
||||||
override val isFinal: Boolean
|
|
||||||
get() = JavaElementUtil.isFinal(this)
|
|
||||||
|
|
||||||
override val visibility: Visibility
|
|
||||||
get() = JavaElementUtil.getVisibility(this)
|
|
||||||
|
|
||||||
override val lightClassOriginKind: LightClassOriginKind?
|
|
||||||
get() = (psi as? KtLightClassMarker)?.originKind
|
|
||||||
|
|
||||||
override val virtualFile: VirtualFile?
|
|
||||||
get() = psi.containingFile?.virtualFile
|
|
||||||
|
|
||||||
override fun isFromSourceCodeInScope(scope: SearchScope): Boolean = psi.containingFile.virtualFile in scope
|
|
||||||
|
|
||||||
override fun getAnnotationOwnerPsi() = psi.modifierList
|
|
||||||
|
|
||||||
private fun assertNotLightClass() {
|
|
||||||
val psiClass = psi
|
|
||||||
if (psiClass !is KtLightClassMarker) return
|
|
||||||
|
|
||||||
val message = "Querying members of JavaClass created for $psiClass of type ${psiClass::class.java} defined in file ${psiClass.containingFile?.virtualFile?.canonicalPath}"
|
|
||||||
LOGGER.error(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private val LOGGER = Logger.getInstance(JavaClassImpl::class.java)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-113
@@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.load.java.structure.impl;
|
|
||||||
|
|
||||||
import com.intellij.codeInsight.ExternalAnnotationsManager;
|
|
||||||
import com.intellij.psi.PsiAnnotation;
|
|
||||||
import com.intellij.psi.PsiAnnotationOwner;
|
|
||||||
import com.intellij.psi.PsiModifier;
|
|
||||||
import com.intellij.psi.PsiModifierListOwner;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities;
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility;
|
|
||||||
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities;
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation;
|
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.annotations;
|
|
||||||
import static org.jetbrains.kotlin.load.java.structure.impl.JavaElementCollectionFromPsiArrayUtil.nullabilityAnnotations;
|
|
||||||
|
|
||||||
/* package */ class JavaElementUtil {
|
|
||||||
private JavaElementUtil() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isAbstract(@NotNull JavaModifierListOwnerImpl owner) {
|
|
||||||
return owner.getPsi().hasModifierProperty(PsiModifier.ABSTRACT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isStatic(@NotNull JavaModifierListOwnerImpl owner) {
|
|
||||||
return owner.getPsi().hasModifierProperty(PsiModifier.STATIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isFinal(@NotNull JavaModifierListOwnerImpl owner) {
|
|
||||||
return owner.getPsi().hasModifierProperty(PsiModifier.FINAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isSealed(@NotNull JavaModifierListOwnerImpl owner) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static Visibility getVisibility(@NotNull JavaModifierListOwnerImpl owner) {
|
|
||||||
PsiModifierListOwner psiOwner = owner.getPsi();
|
|
||||||
if (psiOwner.hasModifierProperty(PsiModifier.PUBLIC)) {
|
|
||||||
return Visibilities.Public.INSTANCE;
|
|
||||||
}
|
|
||||||
if (psiOwner.hasModifierProperty(PsiModifier.PRIVATE)) {
|
|
||||||
return Visibilities.Private.INSTANCE;
|
|
||||||
}
|
|
||||||
if (psiOwner.hasModifierProperty(PsiModifier.PROTECTED)) {
|
|
||||||
return owner.isStatic() ? JavaVisibilities.ProtectedStaticVisibility.INSTANCE : JavaVisibilities.ProtectedAndPackage.INSTANCE;
|
|
||||||
}
|
|
||||||
return JavaVisibilities.PackageVisibility.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static Collection<JavaAnnotation> getAnnotations(@NotNull JavaAnnotationOwnerImpl owner) {
|
|
||||||
PsiAnnotationOwner annotationOwnerPsi = owner.getAnnotationOwnerPsi();
|
|
||||||
if (annotationOwnerPsi != null) {
|
|
||||||
return annotations(annotationOwnerPsi.getAnnotations());
|
|
||||||
}
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static PsiAnnotation[] getExternalAnnotations(@NotNull JavaModifierListOwnerImpl modifierListOwner) {
|
|
||||||
PsiModifierListOwner psiModifierListOwner = modifierListOwner.getPsi();
|
|
||||||
ExternalAnnotationsManager externalAnnotationManager = ExternalAnnotationsManager
|
|
||||||
.getInstance(psiModifierListOwner.getProject());
|
|
||||||
return externalAnnotationManager.findExternalAnnotations(psiModifierListOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
static <T extends JavaAnnotationOwnerImpl & JavaModifierListOwnerImpl>
|
|
||||||
Collection<JavaAnnotation> getRegularAndExternalAnnotations(@NotNull T owner) {
|
|
||||||
PsiAnnotation[] externalAnnotations = getExternalAnnotations(owner);
|
|
||||||
if (externalAnnotations == null) {
|
|
||||||
return getAnnotations(owner);
|
|
||||||
}
|
|
||||||
Collection<JavaAnnotation> annotations = new ArrayList<>(getAnnotations(owner));
|
|
||||||
annotations.addAll(nullabilityAnnotations(externalAnnotations));
|
|
||||||
return annotations;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static JavaAnnotation findAnnotation(@NotNull JavaAnnotationOwnerImpl owner, @NotNull FqName fqName) {
|
|
||||||
PsiAnnotationOwner annotationOwnerPsi = owner.getAnnotationOwnerPsi();
|
|
||||||
if (annotationOwnerPsi != null) {
|
|
||||||
PsiAnnotation psiAnnotation = annotationOwnerPsi.findAnnotation(fqName.asString());
|
|
||||||
return psiAnnotation == null ? null : new JavaAnnotationImpl(psiAnnotation);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-247
@@ -1,247 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.load.java.structure.impl.classFiles
|
|
||||||
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
|
||||||
import com.intellij.psi.search.SearchScope
|
|
||||||
import gnu.trove.THashMap
|
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.*
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.VirtualFileBoundJavaClass
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaAnnotation.Companion.computeTypeParameterBound
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
|
||||||
import org.jetbrains.org.objectweb.asm.*
|
|
||||||
import java.text.CharacterIterator
|
|
||||||
import java.text.StringCharacterIterator
|
|
||||||
|
|
||||||
class BinaryJavaClass(
|
|
||||||
override val virtualFile: VirtualFile,
|
|
||||||
override val fqName: FqName,
|
|
||||||
internal val context: ClassifierResolutionContext,
|
|
||||||
private val signatureParser: BinaryClassSignatureParser,
|
|
||||||
override var access: Int = 0,
|
|
||||||
override val outerClass: JavaClass?,
|
|
||||||
classContent: ByteArray? = null
|
|
||||||
) : ClassVisitor(ASM_API_VERSION_FOR_CLASS_READING), VirtualFileBoundJavaClass, BinaryJavaModifierListOwner, MutableJavaAnnotationOwner {
|
|
||||||
override val annotations: MutableCollection<JavaAnnotation> = SmartList()
|
|
||||||
|
|
||||||
override lateinit var typeParameters: List<JavaTypeParameter>
|
|
||||||
override lateinit var supertypes: List<JavaClassifierType>
|
|
||||||
|
|
||||||
override val methods = arrayListOf<JavaMethod>()
|
|
||||||
override val fields = arrayListOf<JavaField>()
|
|
||||||
override val constructors = arrayListOf<JavaConstructor>()
|
|
||||||
override val recordComponents = arrayListOf<JavaRecordComponent>()
|
|
||||||
|
|
||||||
override fun hasDefaultConstructor() = false // never: all constructors explicit in bytecode
|
|
||||||
|
|
||||||
private lateinit var myInternalName: String
|
|
||||||
|
|
||||||
// In accordance with JVMS, super class always comes before the interface list
|
|
||||||
private val superclass: JavaClassifierType? get() = supertypes.firstOrNull()
|
|
||||||
private val implementedInterfaces: List<JavaClassifierType> get() = supertypes.drop(1)
|
|
||||||
|
|
||||||
override val annotationsByFqName by buildLazyValueForMap()
|
|
||||||
|
|
||||||
// Short name of a nested class of this class -> access flags as seen in the InnerClasses attribute value.
|
|
||||||
// Note that it doesn't include classes mentioned in other InnerClasses attribute values (those which are not nested in this class).
|
|
||||||
private val ownInnerClassNameToAccess: MutableMap<Name, Int> = THashMap()
|
|
||||||
|
|
||||||
override val innerClassNames get() = ownInnerClassNameToAccess.keys
|
|
||||||
|
|
||||||
override val name: Name
|
|
||||||
get() = fqName.shortName()
|
|
||||||
|
|
||||||
override val isInterface get() = isSet(Opcodes.ACC_INTERFACE)
|
|
||||||
override val isAnnotationType get() = isSet(Opcodes.ACC_ANNOTATION)
|
|
||||||
override val isEnum get() = isSet(Opcodes.ACC_ENUM)
|
|
||||||
|
|
||||||
override val isRecord get() = false
|
|
||||||
|
|
||||||
override val lightClassOriginKind: LightClassOriginKind? get() = null
|
|
||||||
|
|
||||||
override val isSealed: Boolean get() = permittedTypes.isNotEmpty()
|
|
||||||
override val permittedTypes = arrayListOf<JavaClassifierType>()
|
|
||||||
|
|
||||||
override fun isFromSourceCodeInScope(scope: SearchScope): Boolean = false
|
|
||||||
|
|
||||||
override fun visitTypeAnnotation(typeRef: Int, typePath: TypePath?, descriptor: String?, visible: Boolean): AnnotationVisitor? {
|
|
||||||
if (descriptor == null)
|
|
||||||
return null
|
|
||||||
|
|
||||||
fun getTargetType(baseType: JavaType) =
|
|
||||||
if (typePath != null) BinaryJavaAnnotation.computeTargetType(baseType, typePath) else baseType
|
|
||||||
|
|
||||||
val typeReference = TypeReference(typeRef)
|
|
||||||
|
|
||||||
val annotationOwner = when (typeReference.sort) {
|
|
||||||
TypeReference.CLASS_EXTENDS ->
|
|
||||||
getTargetType(if (typeReference.superTypeIndex == -1) superclass!! else implementedInterfaces[typeReference.superTypeIndex])
|
|
||||||
TypeReference.CLASS_TYPE_PARAMETER -> typeParameters[typeReference.typeParameterIndex]
|
|
||||||
TypeReference.CLASS_TYPE_PARAMETER_BOUND -> getTargetType(computeTypeParameterBound(typeParameters, typeReference))
|
|
||||||
else -> return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (annotationOwner !is MutableJavaAnnotationOwner) return null
|
|
||||||
|
|
||||||
return BinaryJavaAnnotation.addAnnotation(annotationOwner, descriptor, context, signatureParser, isFreshlySupportedAnnotation = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitEnd() {
|
|
||||||
methods.trimToSize()
|
|
||||||
fields.trimToSize()
|
|
||||||
constructors.trimToSize()
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
try {
|
|
||||||
ClassReader(classContent ?: virtualFile.contentsToByteArray()).accept(
|
|
||||||
this,
|
|
||||||
ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES
|
|
||||||
)
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
throw IllegalStateException("Could not read class: $virtualFile", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
|
||||||
if (access.isSet(Opcodes.ACC_SYNTHETIC) || access.isSet(Opcodes.ACC_BRIDGE) || name == "<clinit>") return null
|
|
||||||
|
|
||||||
// skip semi-synthetic enum methods
|
|
||||||
if (isEnum) {
|
|
||||||
if (name == "values" && desc.startsWith("()")) return null
|
|
||||||
if (name == "valueOf" && desc.startsWith("(Ljava/lang/String;)")) return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val (member, visitor) = BinaryJavaMethodBase.create(name, access, desc, signature, this, context.copyForMember(), signatureParser)
|
|
||||||
|
|
||||||
when (member) {
|
|
||||||
is JavaMethod -> methods.add(member)
|
|
||||||
is JavaConstructor -> constructors.add(member)
|
|
||||||
else -> error("Unexpected member: ${member.javaClass}")
|
|
||||||
}
|
|
||||||
|
|
||||||
return visitor
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitInnerClass(name: String, outerName: String?, innerName: String?, access: Int) {
|
|
||||||
if (access.isSet(Opcodes.ACC_SYNTHETIC)) return
|
|
||||||
if (innerName == null || outerName == null) return
|
|
||||||
|
|
||||||
// Do not read InnerClasses attribute values where full name != outer + $ + inner; treat those classes as top level instead.
|
|
||||||
// This is possible for example for Groovy-generated $Trait$FieldHelper classes.
|
|
||||||
if (name == "$outerName$$innerName") {
|
|
||||||
context.addInnerClass(name, outerName, innerName)
|
|
||||||
|
|
||||||
if (myInternalName == outerName) {
|
|
||||||
ownInnerClassNameToAccess[context.mapInternalNameToClassId(name).shortClassName] = access
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visit(
|
|
||||||
version: Int,
|
|
||||||
access: Int,
|
|
||||||
name: String,
|
|
||||||
signature: String?,
|
|
||||||
superName: String?,
|
|
||||||
interfaces: Array<out String>?
|
|
||||||
) {
|
|
||||||
this.access = this.access or access
|
|
||||||
this.myInternalName = name
|
|
||||||
|
|
||||||
if (signature != null) {
|
|
||||||
parseClassSignature(signature)
|
|
||||||
} else {
|
|
||||||
this.typeParameters = emptyList()
|
|
||||||
this.supertypes = mutableListOf<JavaClassifierType>().apply {
|
|
||||||
addIfNotNull(superName?.convertInternalNameToClassifierType())
|
|
||||||
interfaces?.forEach {
|
|
||||||
addIfNotNull(it.convertInternalNameToClassifierType())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseClassSignature(signature: String) {
|
|
||||||
val iterator = StringCharacterIterator(signature)
|
|
||||||
this.typeParameters =
|
|
||||||
signatureParser
|
|
||||||
.parseTypeParametersDeclaration(iterator, context)
|
|
||||||
.also(context::addTypeParameters)
|
|
||||||
|
|
||||||
val supertypes = SmartList<JavaClassifierType>()
|
|
||||||
supertypes.addIfNotNull(signatureParser.parseClassifierRefSignature(iterator, context))
|
|
||||||
while (iterator.current() != CharacterIterator.DONE) {
|
|
||||||
supertypes.addIfNotNull(signatureParser.parseClassifierRefSignature(iterator, context))
|
|
||||||
}
|
|
||||||
this.supertypes = supertypes
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun String.convertInternalNameToClassifierType(): JavaClassifierType =
|
|
||||||
PlainJavaClassifierType({ context.resolveByInternalName(this) }, emptyList())
|
|
||||||
|
|
||||||
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
|
|
||||||
if (access.isSet(Opcodes.ACC_SYNTHETIC)) return null
|
|
||||||
|
|
||||||
val type = signatureParser.parseTypeString(StringCharacterIterator(signature ?: desc), context)
|
|
||||||
val processedValue = processValue(value, type)
|
|
||||||
val filed = BinaryJavaField(Name.identifier(name), access, this, access.isSet(Opcodes.ACC_ENUM), type, processedValue)
|
|
||||||
|
|
||||||
fields.add(filed)
|
|
||||||
|
|
||||||
return AnnotationsCollectorFieldVisitor(filed, context, signatureParser)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All the int-like values (including Char/Boolean) come in visitor as Integer instances
|
|
||||||
*/
|
|
||||||
private fun processValue(value: Any?, fieldType: JavaType): Any? {
|
|
||||||
if (fieldType !is JavaPrimitiveType || fieldType.type == null || value !is Int) return value
|
|
||||||
|
|
||||||
return when (fieldType.type) {
|
|
||||||
PrimitiveType.BOOLEAN -> {
|
|
||||||
when (value) {
|
|
||||||
0 -> false
|
|
||||||
1 -> true
|
|
||||||
else -> value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PrimitiveType.CHAR -> value.toChar()
|
|
||||||
else -> value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitAnnotation(desc: String, visible: Boolean) =
|
|
||||||
BinaryJavaAnnotation.addAnnotation(this, desc, context, signatureParser)
|
|
||||||
|
|
||||||
override fun findInnerClass(name: Name): JavaClass? = findInnerClass(name, classFileContent = null)
|
|
||||||
|
|
||||||
fun findInnerClass(name: Name, classFileContent: ByteArray?): JavaClass? {
|
|
||||||
val access = ownInnerClassNameToAccess[name] ?: return null
|
|
||||||
|
|
||||||
return virtualFile.parent.findChild("${virtualFile.nameWithoutExtension}$$name.class")?.let {
|
|
||||||
BinaryJavaClass(
|
|
||||||
it, fqName.child(name), context.copyForMember(), signatureParser, access, this,
|
|
||||||
classFileContent
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-346
@@ -1,346 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2000-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.test.testFramework;
|
|
||||||
|
|
||||||
import com.intellij.core.CoreASTFactory;
|
|
||||||
import com.intellij.ide.util.AppPropertiesComponentImpl;
|
|
||||||
import com.intellij.ide.util.PropertiesComponent;
|
|
||||||
import com.intellij.lang.*;
|
|
||||||
import com.intellij.lang.impl.PsiBuilderFactoryImpl;
|
|
||||||
import com.intellij.mock.*;
|
|
||||||
import com.intellij.openapi.Disposable;
|
|
||||||
import com.intellij.openapi.application.PathManager;
|
|
||||||
import com.intellij.openapi.editor.Document;
|
|
||||||
import com.intellij.openapi.editor.EditorFactory;
|
|
||||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
|
||||||
import com.intellij.openapi.extensions.Extensions;
|
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
|
||||||
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
|
|
||||||
import com.intellij.openapi.fileTypes.FileTypeFactory;
|
|
||||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
|
||||||
import com.intellij.openapi.fileTypes.FileTypeRegistry;
|
|
||||||
import com.intellij.openapi.options.SchemeManagerFactory;
|
|
||||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
|
||||||
import com.intellij.openapi.progress.ProgressManager;
|
|
||||||
import com.intellij.openapi.progress.impl.CoreProgressManager;
|
|
||||||
import com.intellij.openapi.util.Disposer;
|
|
||||||
import com.intellij.openapi.util.Key;
|
|
||||||
import com.intellij.openapi.util.TextRange;
|
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
|
||||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
|
||||||
import com.intellij.pom.PomModel;
|
|
||||||
import com.intellij.pom.core.impl.PomModelImpl;
|
|
||||||
import com.intellij.pom.tree.TreeAspect;
|
|
||||||
import com.intellij.psi.*;
|
|
||||||
import com.intellij.psi.impl.*;
|
|
||||||
import com.intellij.psi.util.CachedValuesManager;
|
|
||||||
import com.intellij.testFramework.LightVirtualFile;
|
|
||||||
import com.intellij.testFramework.MockSchemeManagerFactory;
|
|
||||||
import com.intellij.testFramework.TestDataFile;
|
|
||||||
import com.intellij.util.CachedValuesManagerImpl;
|
|
||||||
import com.intellij.util.Function;
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
import org.jetbrains.annotations.NonNls;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinFileType;
|
|
||||||
import org.picocontainer.ComponentAdapter;
|
|
||||||
import org.picocontainer.MutablePicoContainer;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
|
||||||
public abstract class KtParsingTestCase extends KtPlatformLiteFixture {
|
|
||||||
public static final Key<Document> HARD_REF_TO_DOCUMENT_KEY = Key.create("HARD_REF_TO_DOCUMENT_KEY");
|
|
||||||
protected String myFilePrefix = "";
|
|
||||||
protected String myFileExt;
|
|
||||||
protected final String myFullDataPath;
|
|
||||||
protected PsiFile myFile;
|
|
||||||
private MockPsiManager myPsiManager;
|
|
||||||
private PsiFileFactoryImpl myFileFactory;
|
|
||||||
protected Language myLanguage;
|
|
||||||
private final ParserDefinition[] myDefinitions;
|
|
||||||
private final boolean myLowercaseFirstLetter;
|
|
||||||
|
|
||||||
protected KtParsingTestCase(@NonNls @NotNull String dataPath, @NotNull String fileExt, @NotNull ParserDefinition... definitions) {
|
|
||||||
this(dataPath, fileExt, false, definitions);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected KtParsingTestCase(@NonNls @NotNull String dataPath, @NotNull String fileExt, boolean lowercaseFirstLetter, @NotNull ParserDefinition... definitions) {
|
|
||||||
myDefinitions = definitions;
|
|
||||||
myFullDataPath = getTestDataPath() + "/" + dataPath;
|
|
||||||
myFileExt = fileExt;
|
|
||||||
myLowercaseFirstLetter = lowercaseFirstLetter;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
initApplication();
|
|
||||||
ComponentAdapter component = getApplication().getPicoContainer().getComponentAdapter(ProgressManager.class.getName());
|
|
||||||
|
|
||||||
Extensions.registerAreaClass("IDEA_PROJECT", null);
|
|
||||||
myProject = new MockProjectEx(getTestRootDisposable());
|
|
||||||
myPsiManager = new MockPsiManager(myProject);
|
|
||||||
myFileFactory = new PsiFileFactoryImpl(myPsiManager);
|
|
||||||
MutablePicoContainer appContainer = getApplication().getPicoContainer();
|
|
||||||
final MockEditorFactory editorFactory = new MockEditorFactory();
|
|
||||||
MockFileTypeManager mockFileTypeManager = new MockFileTypeManager(KotlinFileType.INSTANCE);
|
|
||||||
MockFileDocumentManagerImpl mockFileDocumentManager = new MockFileDocumentManagerImpl(new Function<CharSequence, Document>() {
|
|
||||||
@Override
|
|
||||||
public Document fun(CharSequence charSequence) {
|
|
||||||
return editorFactory.createDocument(charSequence);
|
|
||||||
}
|
|
||||||
}, HARD_REF_TO_DOCUMENT_KEY);
|
|
||||||
|
|
||||||
registerApplicationService(PropertiesComponent.class, new AppPropertiesComponentImpl());
|
|
||||||
registerApplicationService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl());
|
|
||||||
registerApplicationService(DefaultASTFactory.class, new CoreASTFactory());
|
|
||||||
registerApplicationService(SchemeManagerFactory.class, new MockSchemeManagerFactory());
|
|
||||||
registerApplicationService(FileTypeManager.class, mockFileTypeManager);
|
|
||||||
registerApplicationService(FileDocumentManager.class, mockFileDocumentManager);
|
|
||||||
|
|
||||||
registerApplicationService(ProgressManager.class, new CoreProgressManager());
|
|
||||||
|
|
||||||
registerComponentInstance(appContainer, FileTypeRegistry.class, mockFileTypeManager);
|
|
||||||
registerComponentInstance(appContainer, FileTypeManager.class, mockFileTypeManager);
|
|
||||||
registerComponentInstance(appContainer, EditorFactory.class, editorFactory);
|
|
||||||
registerComponentInstance(appContainer, FileDocumentManager.class, mockFileDocumentManager);
|
|
||||||
registerComponentInstance(appContainer, PsiDocumentManager.class, new MockPsiDocumentManager());
|
|
||||||
|
|
||||||
|
|
||||||
myProject.registerService(CachedValuesManager.class, new CachedValuesManagerImpl(myProject, new PsiCachedValuesFactory(myPsiManager)));
|
|
||||||
myProject.registerService(PsiManager.class, myPsiManager);
|
|
||||||
|
|
||||||
this.registerExtensionPoint(FileTypeFactory.FILE_TYPE_FACTORY_EP, FileTypeFactory.class);
|
|
||||||
registerExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
|
||||||
|
|
||||||
for (ParserDefinition definition : myDefinitions) {
|
|
||||||
addExplicitExtension(LanguageParserDefinitions.INSTANCE, definition.getFileNodeType().getLanguage(), definition);
|
|
||||||
}
|
|
||||||
if (myDefinitions.length > 0) {
|
|
||||||
configureFromParserDefinition(myDefinitions[0], myFileExt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// That's for reparse routines
|
|
||||||
final PomModelImpl pomModel = new PomModelImpl(myProject);
|
|
||||||
myProject.registerService(PomModel.class, pomModel);
|
|
||||||
new TreeAspect(pomModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void configureFromParserDefinition(ParserDefinition definition, String extension) {
|
|
||||||
myLanguage = definition.getFileNodeType().getLanguage();
|
|
||||||
myFileExt = extension;
|
|
||||||
addExplicitExtension(LanguageParserDefinitions.INSTANCE, this.myLanguage, definition);
|
|
||||||
registerComponentInstance(
|
|
||||||
getApplication().getPicoContainer(), FileTypeManager.class,
|
|
||||||
new MockFileTypeManager(new MockLanguageFileType(myLanguage, myFileExt)));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T> void addExplicitExtension(final LanguageExtension<T> instance, final Language language, final T object) {
|
|
||||||
instance.addExplicitExtension(language, object);
|
|
||||||
Disposer.register(myProject, new Disposable() {
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
instance.removeExplicitExtension(language, object);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected <T> void registerExtensionPoint(final ExtensionPointName<T> extensionPointName, Class<T> aClass) {
|
|
||||||
super.registerExtensionPoint(extensionPointName, aClass);
|
|
||||||
Disposer.register(myProject, new Disposable() {
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
Extensions.getRootArea().unregisterExtensionPoint(extensionPointName.getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
protected <T> void registerApplicationService(final Class<T> aClass, T object) {
|
|
||||||
getApplication().registerService(aClass, object);
|
|
||||||
Disposer.register(myProject, new Disposable() {
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
getApplication().getPicoContainer().unregisterComponent(aClass.getName());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public MockProjectEx getProject() {
|
|
||||||
return myProject;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MockPsiManager getPsiManager() {
|
|
||||||
return myPsiManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void tearDown() throws Exception {
|
|
||||||
super.tearDown();
|
|
||||||
myFile = null;
|
|
||||||
myProject = null;
|
|
||||||
myPsiManager = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getTestDataPath() {
|
|
||||||
return PathManager.getHomePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public final String getTestName() {
|
|
||||||
return getTestName(myLowercaseFirstLetter);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean includeRanges() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean skipSpaces() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean checkAllPsiRoots() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doTest(boolean checkResult) {
|
|
||||||
String name = getTestName();
|
|
||||||
try {
|
|
||||||
String text = loadFile(name + "." + myFileExt);
|
|
||||||
myFile = createPsiFile(name, text);
|
|
||||||
ensureParsed(myFile);
|
|
||||||
assertEquals("light virtual file text mismatch", text, ((LightVirtualFile)myFile.getVirtualFile()).getContent().toString());
|
|
||||||
assertEquals("virtual file text mismatch", text, LoadTextUtil.loadText(myFile.getVirtualFile()));
|
|
||||||
assertEquals("doc text mismatch", text, myFile.getViewProvider().getDocument().getText());
|
|
||||||
assertEquals("psi text mismatch", text, myFile.getText());
|
|
||||||
ensureCorrectReparse(myFile);
|
|
||||||
if (checkResult){
|
|
||||||
checkResult(name, myFile);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
toParseTreeText(myFile, skipSpaces(), includeRanges());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doTest(String suffix) throws IOException {
|
|
||||||
String name = getTestName();
|
|
||||||
String text = loadFile(name + "." + myFileExt);
|
|
||||||
myFile = createPsiFile(name, text);
|
|
||||||
ensureParsed(myFile);
|
|
||||||
assertEquals(text, myFile.getText());
|
|
||||||
checkResult(name + suffix, myFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doCodeTest(String code) throws IOException {
|
|
||||||
String name = getTestName();
|
|
||||||
myFile = createPsiFile("a", code);
|
|
||||||
ensureParsed(myFile);
|
|
||||||
assertEquals(code, myFile.getText());
|
|
||||||
checkResult(myFilePrefix + name, myFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected PsiFile createPsiFile(String name, String text) {
|
|
||||||
return createFile(name + "." + myFileExt, text);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected PsiFile createFile(@NonNls String name, String text) {
|
|
||||||
LightVirtualFile virtualFile = new LightVirtualFile(name, myLanguage, text);
|
|
||||||
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
|
||||||
return createFile(virtualFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected PsiFile createFile(LightVirtualFile virtualFile) {
|
|
||||||
return myFileFactory.trySetupPsiForFile(virtualFile, myLanguage, true, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void checkResult(@NonNls @TestDataFile String targetDataName, final PsiFile file) throws IOException {
|
|
||||||
doCheckResult(myFullDataPath, file, checkAllPsiRoots(), targetDataName, skipSpaces(), includeRanges());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void doCheckResult(String testDataDir,
|
|
||||||
PsiFile file,
|
|
||||||
boolean checkAllPsiRoots,
|
|
||||||
String targetDataName,
|
|
||||||
boolean skipSpaces,
|
|
||||||
boolean printRanges) throws IOException {
|
|
||||||
FileViewProvider provider = file.getViewProvider();
|
|
||||||
Set<Language> languages = provider.getLanguages();
|
|
||||||
|
|
||||||
if (!checkAllPsiRoots || languages.size() == 1) {
|
|
||||||
doCheckResult(testDataDir, targetDataName + ".txt", toParseTreeText(file, skipSpaces, printRanges).trim());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Language language : languages) {
|
|
||||||
PsiFile root = provider.getPsi(language);
|
|
||||||
String expectedName = targetDataName + "." + language.getID() + ".txt";
|
|
||||||
doCheckResult(testDataDir, expectedName, toParseTreeText(root, skipSpaces, printRanges).trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void checkResult(String actual) throws IOException {
|
|
||||||
String name = getTestName();
|
|
||||||
doCheckResult(myFullDataPath, myFilePrefix + name + ".txt", actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void checkResult(@TestDataFile @NonNls String targetDataName, String actual) throws IOException {
|
|
||||||
doCheckResult(myFullDataPath, targetDataName, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void doCheckResult(String fullPath, String targetDataName, String actual) throws IOException {
|
|
||||||
String expectedFileName = fullPath + File.separatorChar + targetDataName;
|
|
||||||
KtUsefulTestCase.assertSameLinesWithFile(expectedFileName, actual);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static String toParseTreeText(PsiElement file, boolean skipSpaces, boolean printRanges) {
|
|
||||||
return DebugUtil.psiToString(file, skipSpaces, printRanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String loadFile(@NonNls @TestDataFile String name) throws IOException {
|
|
||||||
return loadFileDefault(myFullDataPath, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String loadFileDefault(String dir, String name) throws IOException {
|
|
||||||
return FileUtil.loadFile(new File(dir, name), CharsetToolkit.UTF8, true).trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ensureParsed(PsiFile file) {
|
|
||||||
file.accept(new PsiElementVisitor() {
|
|
||||||
@Override
|
|
||||||
public void visitElement(PsiElement element) {
|
|
||||||
element.acceptChildren(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ensureCorrectReparse(@NotNull PsiFile file) {
|
|
||||||
String psiToStringDefault = DebugUtil.psiToString(file, false, false);
|
|
||||||
String fileText = file.getText();
|
|
||||||
DiffLog diffLog = (new BlockSupportImpl()).reparseRange(
|
|
||||||
file, file.getNode(), TextRange.allOf(fileText), fileText, new EmptyProgressIndicator(), fileText);
|
|
||||||
diffLog.performActualPsiChange(file);
|
|
||||||
|
|
||||||
TestCase.assertEquals(psiToStringDefault, DebugUtil.psiToString(file, false, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-1187
File diff suppressed because it is too large
Load Diff
-1186
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.utils
|
|
||||||
|
|
||||||
import com.intellij.util.containers.ConcurrentMultiMap
|
|
||||||
import com.intellij.util.containers.Interner
|
|
||||||
import com.intellij.util.containers.MultiMap
|
|
||||||
import com.intellij.util.containers.StringInterner
|
|
||||||
|
|
||||||
fun createStringInterner(): Interner<String> =
|
|
||||||
StringInterner()
|
|
||||||
|
|
||||||
fun <K, V> createConcurrentMultiMap(): MultiMap<K, V> =
|
|
||||||
ConcurrentMultiMap<K, V>()
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
|
||||||
@@ -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
|
|
||||||
idea/idea-completion/testData/basic/multifile/PropertyKeysEmptyString/PropertyKeysEmptyString.kt.201
Vendored
-13
@@ -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
|
|
||||||
Vendored
-13
@@ -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
|
|
||||||
Vendored
-12
@@ -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
|
|
||||||
@@ -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() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-3
@@ -1,3 +0,0 @@
|
|||||||
class ProjectConfigurationCollector {
|
|
||||||
// Not whitelisted
|
|
||||||
}
|
|
||||||
@@ -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())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-8
@@ -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
|
|
||||||
-8
@@ -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
|
|
||||||
-1
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
|
|||||||
import org.jetbrains.plugins.gradle.service.project.open.linkAndRefreshGradleProject
|
import org.jetbrains.plugins.gradle.service.project.open.linkAndRefreshGradleProject
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
// FIX ME WHEN BUNCH 201 REMOVED
|
|
||||||
class IdeaGradleWizardService(private val project: Project) : ProjectImportingWizardService,
|
class IdeaGradleWizardService(private val project: Project) : ProjectImportingWizardService,
|
||||||
IdeaWizardService {
|
IdeaWizardService {
|
||||||
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean =
|
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean =
|
||||||
|
|||||||
-15
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-1
@@ -95,7 +95,6 @@ abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFix
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
runPostStartupActivitiesOnce(project)
|
|
||||||
VfsRootAccess.allowRootAccess(project, KtTestUtil.getHomeDirectory())
|
VfsRootAccess.allowRootAccess(project, KtTestUtil.getHomeDirectory())
|
||||||
|
|
||||||
EditorTracker.getInstance(project)
|
EditorTracker.getInstance(project)
|
||||||
|
|||||||
-98
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-1
@@ -26,7 +26,6 @@ abstract class KotlinLightPlatformCodeInsightFixtureTestCase : LightPlatformCode
|
|||||||
override fun setUp() {
|
override fun setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
enableKotlinOfficialCodeStyle(project)
|
enableKotlinOfficialCodeStyle(project)
|
||||||
runPostStartupActivitiesOnce(project)
|
|
||||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
|
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
|
||||||
if (!isFirPlugin()) {
|
if (!isFirPlugin()) {
|
||||||
invalidateLibraryCache(project)
|
invalidateLibraryCache(project)
|
||||||
|
|||||||
-137
@@ -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);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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) {
|
|
||||||
}
|
|
||||||
@@ -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()
|
|
||||||
}
|
|
||||||
-120
@@ -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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-299
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-5
@@ -221,11 +221,7 @@ private class Printer(private val delegate: FramePrinterDelegate, private val co
|
|||||||
|
|
||||||
if (config.shouldRenderExpression() && descriptor is ValueDescriptorImpl) {
|
if (config.shouldRenderExpression() && descriptor is ValueDescriptorImpl) {
|
||||||
val expression = debugProcess.invokeInManagerThread { debuggerContextImpl ->
|
val expression = debugProcess.invokeInManagerThread { debuggerContextImpl ->
|
||||||
descriptor.getTreeEvaluation((node as XValueNodeImpl).valueContainer as JavaValue, debuggerContextImpl).let {
|
descriptor.getTreeEvaluation((node as XValueNodeImpl).valueContainer as JavaValue, debuggerContextImpl).get()
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
|
|||||||
-82
@@ -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()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-120
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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">What’s 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">What’s 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">What’s 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>
|
|
||||||
@@ -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">What’s 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">What’s 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">What’s 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>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<idea-plugin>
|
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
|
||||||
<externalAnnotator language="kotlin" implementationClass="org.jetbrains.android.inspections.lint.AndroidLintExternalAnnotator"/>
|
|
||||||
</extensions>
|
|
||||||
</idea-plugin>
|
|
||||||
-380
@@ -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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-75
@@ -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)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
class IDESettingsFUSCollector {
|
|
||||||
// Not whitelisted
|
|
||||||
}
|
|
||||||
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
// FIX ME WHEN BUNCH 201 REMOVED
|
|
||||||
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase() {
|
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase() {
|
||||||
|
|
||||||
override fun collectDocComments(file: PsiFile, sink: Consumer<PsiDocCommentBase>) {
|
override fun collectDocComments(file: PsiFile, sink: Consumer<PsiDocCommentBase>) {
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
// FIX ME WHEN BUNCH 201 REMOVED
|
|
||||||
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase() {
|
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase() {
|
||||||
|
|
||||||
override fun collectDocComments(file: PsiFile, sink: Consumer<in PsiDocCommentBase>) {
|
override fun collectDocComments(file: PsiFile, sink: Consumer<in PsiDocCommentBase>) {
|
||||||
|
|||||||
@@ -34,18 +34,14 @@ import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade;
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm;
|
||||||
import org.jetbrains.kotlin.resolve.konan.diagnostics.ErrorsNative;
|
import org.jetbrains.kotlin.resolve.konan.diagnostics.ErrorsNative;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.idea.TestResourceBundleKt.registerAdditionalResourceBundleInTests;
|
|
||||||
|
|
||||||
public class PluginStartupActivity implements StartupActivity {
|
public class PluginStartupActivity implements StartupActivity {
|
||||||
private static final Logger LOG = Logger.getInstance(PluginStartupActivity.class);
|
private static final Logger LOG = Logger.getInstance(PluginStartupActivity.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void runActivity(@NotNull Project project) {
|
public void runActivity(@NotNull Project project) {
|
||||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
|
||||||
registerAdditionalResourceBundleInTests();
|
|
||||||
}
|
|
||||||
|
|
||||||
StartupCompatKt.runActivity(project);
|
StartupKt.runActivity(project);
|
||||||
PluginStartupService.Companion.getInstance(project).register(project);
|
PluginStartupService.Companion.getInstance(project).register(project);
|
||||||
|
|
||||||
project.getMessageBus().connect().subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
|
project.getMessageBus().connect().subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -5,11 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.codeInsight
|
package org.jetbrains.kotlin.idea.codeInsight
|
||||||
|
|
||||||
|
import com.intellij.ide.ui.UISettings
|
||||||
import com.intellij.openapi.project.DumbService
|
import com.intellij.openapi.project.DumbService
|
||||||
import com.intellij.openapi.project.IndexNotReadyException
|
import com.intellij.openapi.project.IndexNotReadyException
|
||||||
import com.intellij.psi.ElementDescriptionUtil
|
import com.intellij.psi.ElementDescriptionUtil
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.refactoring.util.RefactoringDescriptionLocation
|
import com.intellij.refactoring.util.RefactoringDescriptionLocation
|
||||||
|
import com.intellij.ui.breadcrumbs.BreadcrumbsProvider
|
||||||
import com.intellij.usageView.UsageViewShortNameLocation
|
import com.intellij.usageView.UsageViewShortNameLocation
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
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 org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
// FIX ME WHEN BUNCH 201 REMOVED
|
class KotlinBreadcrumbsInfoProvider : BreadcrumbsProvider {
|
||||||
class KotlinBreadcrumbsInfoProvider : BreadcrumbsProviderCompatBase() {
|
|
||||||
private abstract class ElementHandler<TElement : KtElement>(val type: KClass<TElement>) {
|
private abstract class ElementHandler<TElement : KtElement>(val type: KClass<TElement>) {
|
||||||
abstract fun elementInfo(element: TElement): String
|
abstract fun elementInfo(element: TElement): String
|
||||||
abstract fun elementTooltip(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 {
|
private companion object {
|
||||||
enum class TextKind(val maxTextLength: Int) {
|
enum class TextKind(val maxTextLength: Int) {
|
||||||
INFO(16), TOOLTIP(100)
|
INFO(16), TOOLTIP(100)
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-174
@@ -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()
|
|
||||||
}
|
|
||||||
-58
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-189
@@ -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
|
|
||||||
}
|
|
||||||
-126
@@ -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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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<*>>
|
|
||||||
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.idea.KotlinIcons
|
|||||||
import org.jetbrains.kotlin.idea.highlighter.dsl.DslHighlighterExtension
|
import org.jetbrains.kotlin.idea.highlighter.dsl.DslHighlighterExtension
|
||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
|
|
||||||
// FIX ME WHEN BUNCH as41 REMOVED
|
// FIX ME WHEN BUNCH as42 REMOVED
|
||||||
internal fun createDslStyleIcon(styleId: Int): Icon {
|
internal fun createDslStyleIcon(styleId: Int): Icon {
|
||||||
val globalScheme = EditorColorsManager.getInstance().globalScheme
|
val globalScheme = EditorColorsManager.getInstance().globalScheme
|
||||||
val markersColor = globalScheme.getAttributes(DslHighlighterExtension.styleById(styleId)).foregroundColor
|
val markersColor = globalScheme.getAttributes(DslHighlighterExtension.styleById(styleId)).foregroundColor
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-27
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+6
-1
@@ -10,6 +10,7 @@ import com.intellij.openapi.project.Project
|
|||||||
import com.intellij.openapi.util.Ref
|
import com.intellij.openapi.util.Ref
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager
|
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.MethodReferencesSearch
|
||||||
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
import com.intellij.psi.search.searches.OverridingMethodsSearch
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
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.CommonRefactoringUtil
|
||||||
import com.intellij.refactoring.util.MoveRenameUsageInfo
|
import com.intellij.refactoring.util.MoveRenameUsageInfo
|
||||||
import com.intellij.refactoring.util.RefactoringUIUtil
|
import com.intellij.refactoring.util.RefactoringUIUtil
|
||||||
|
import com.intellij.refactoring.util.TextOccurrencesUtil
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.util.containers.MultiMap
|
import com.intellij.util.containers.MultiMap
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
@@ -269,7 +271,10 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
|||||||
val oldName = changeInfo.oldName
|
val oldName = changeInfo.oldName
|
||||||
|
|
||||||
if (oldName != null) {
|
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()
|
val oldParameters = (functionPsi as KtNamedDeclaration).getValueParameters()
|
||||||
|
|||||||
-48
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-27
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+5
-2
@@ -22,6 +22,7 @@ import com.intellij.refactoring.move.moveClassesOrPackages.MoveClassHandler
|
|||||||
import com.intellij.refactoring.rename.RenameUtil
|
import com.intellij.refactoring.rename.RenameUtil
|
||||||
import com.intellij.refactoring.util.NonCodeUsageInfo
|
import com.intellij.refactoring.util.NonCodeUsageInfo
|
||||||
import com.intellij.refactoring.util.RefactoringUIUtil
|
import com.intellij.refactoring.util.RefactoringUIUtil
|
||||||
|
import com.intellij.refactoring.util.TextOccurrencesUtil
|
||||||
import com.intellij.usageView.UsageInfo
|
import com.intellij.usageView.UsageInfo
|
||||||
import com.intellij.usageView.UsageViewBundle
|
import com.intellij.usageView.UsageViewBundle
|
||||||
import com.intellij.usageView.UsageViewDescriptor
|
import com.intellij.usageView.UsageViewDescriptor
|
||||||
@@ -224,8 +225,9 @@ class MoveKotlinDeclarationsProcessor(
|
|||||||
val name = lightElement.getKotlinFqName()?.quoteIfNeeded()?.asString()
|
val name = lightElement.getKotlinFqName()?.quoteIfNeeded()?.asString()
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
fun searchForKotlinNameUsages(results: ArrayList<UsageInfo>) {
|
fun searchForKotlinNameUsages(results: ArrayList<UsageInfo>) {
|
||||||
BunchedDeprecation.findNonCodeUsages(
|
TextOccurrencesUtil.findNonCodeUsages(
|
||||||
lightElement,
|
lightElement,
|
||||||
|
GlobalSearchScope.projectScope(lightElement.project),
|
||||||
name,
|
name,
|
||||||
descriptor.searchInCommentsAndStrings,
|
descriptor.searchInCommentsAndStrings,
|
||||||
descriptor.searchInNonCode,
|
descriptor.searchInNonCode,
|
||||||
@@ -242,8 +244,9 @@ class MoveKotlinDeclarationsProcessor(
|
|||||||
elementName
|
elementName
|
||||||
)
|
)
|
||||||
|
|
||||||
BunchedDeprecation.findNonCodeUsages(
|
TextOccurrencesUtil.findNonCodeUsages(
|
||||||
lightElement,
|
lightElement,
|
||||||
|
GlobalSearchScope.projectScope(lightElement.project),
|
||||||
oldFqNameWithFacade,
|
oldFqNameWithFacade,
|
||||||
descriptor.searchInCommentsAndStrings,
|
descriptor.searchInCommentsAndStrings,
|
||||||
descriptor.searchInNonCode,
|
descriptor.searchInNonCode,
|
||||||
|
|||||||
@@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-111
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-1
@@ -14,7 +14,6 @@ import com.intellij.psi.search.GlobalSearchScope
|
|||||||
import com.intellij.util.concurrency.AppExecutorUtil
|
import com.intellij.util.concurrency.AppExecutorUtil
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
|
|
||||||
// FIX ME WHEN BUNCH 201 REMOVED
|
|
||||||
|
|
||||||
fun runActivity(project: Project) {
|
fun runActivity(project: Project) {
|
||||||
nonBlocking(Callable {
|
nonBlocking(Callable {
|
||||||
@@ -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() {
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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() {
|
|
||||||
}
|
|
||||||
@@ -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)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
Vendored
-7
@@ -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>() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-11
@@ -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>() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-7
@@ -1,7 +0,0 @@
|
|||||||
// "Add 'int' as 1st parameter to method 'K'" "true"
|
|
||||||
|
|
||||||
public class J {
|
|
||||||
void foo() {
|
|
||||||
new K(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
// "Add 'int' as 1st parameter to method 'K'" "true"
|
|
||||||
|
|
||||||
public class J {
|
|
||||||
void foo() {
|
|
||||||
new K(<caret>1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
// "Add 'int' as 1st parameter to method 'K'" "true"
|
|
||||||
|
|
||||||
public class J {
|
|
||||||
void foo() {
|
|
||||||
new K(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-7
@@ -1,7 +0,0 @@
|
|||||||
// "Add 'int' as 1st parameter to method 'K'" "true"
|
|
||||||
|
|
||||||
public class J {
|
|
||||||
void foo() {
|
|
||||||
new K(<caret>1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-7
@@ -1,7 +0,0 @@
|
|||||||
// "Add 'int' as 1st parameter to method 'K'" "true"
|
|
||||||
|
|
||||||
public class J {
|
|
||||||
void foo() {
|
|
||||||
new K(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-7
@@ -1,7 +0,0 @@
|
|||||||
// "Add 'int' as 1st parameter to method 'K'" "true"
|
|
||||||
|
|
||||||
public class J {
|
|
||||||
void foo() {
|
|
||||||
new K(<caret>1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-7
@@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-7
@@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-7
@@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
idea/testData/quickfix/changeSignature/jk/jkChangeSecondaryConstructorParameter.before.Main.java.201
Vendored
-7
@@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
// "Add 'int' as 1st parameter to method 'Foo'" "true"
|
|
||||||
|
|
||||||
public class J {
|
|
||||||
void test() {
|
|
||||||
new Foo(<caret>1, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -1,7 +0,0 @@
|
|||||||
// "Add 'int' as 1st parameter to method 'Foo'" "true"
|
|
||||||
|
|
||||||
public class J {
|
|
||||||
void test() {
|
|
||||||
new Foo(<caret>1, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-7
@@ -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
Reference in New Issue
Block a user