mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-26 08:31:31 +00:00
Compare commits
7 Commits
rr/faster_
...
yan.master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa8745978a | ||
|
|
e5951a7b54 | ||
|
|
038a8b9b23 | ||
|
|
05174c7255 | ||
|
|
1789d0116b | ||
|
|
d54699f6a5 | ||
|
|
3f0aaf4454 |
@@ -208,6 +208,7 @@ extra["intellijSeparateSdks"] = intellijSeparateSdks
|
||||
extra["IntellijCoreDependencies"] =
|
||||
listOf(
|
||||
when {
|
||||
Platform[203].orHigher() -> "asm-all-9.0"
|
||||
Platform[202].orHigher() -> "asm-all-8.0.1"
|
||||
else -> "asm-all-7.0.1"
|
||||
},
|
||||
@@ -386,7 +387,7 @@ fun Task.listConfigurationContents(configName: String) {
|
||||
}
|
||||
|
||||
val defaultJvmTarget = "1.8"
|
||||
val defaultJavaHome = jdkPath(if (Platform[203].orHigher()) "11" else defaultJvmTarget)
|
||||
val defaultJavaHome = jdkPath(defaultJvmTarget)
|
||||
val ignoreTestFailures by extra(project.kotlinBuildProperties.ignoreTestFailures)
|
||||
|
||||
allprojects {
|
||||
@@ -956,32 +957,35 @@ tasks {
|
||||
|
||||
register("publishIdeArtifacts") {
|
||||
idePluginDependency {
|
||||
dependsOn(
|
||||
":prepare:ide-plugin-dependencies:android-extensions-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-gradle-statistics-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlinx-serialization-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:noarg-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:sam-with-receiver-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:compiler-components-for-jps:publish",
|
||||
":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide:publish",
|
||||
":kotlin-script-runtime:publish",
|
||||
":kotlin-script-util:publish",
|
||||
":kotlin-scripting-common:publish",
|
||||
":kotlin-scripting-jvm:publish",
|
||||
":kotlin-scripting-compiler:publish",
|
||||
":kotlin-scripting-compiler-impl:publish",
|
||||
":kotlin-android-extensions-runtime:publish",
|
||||
":kotlin-stdlib-common:publish",
|
||||
":kotlin-stdlib:publish",
|
||||
":kotlin-stdlib-jdk7:publish",
|
||||
":kotlin-stdlib-jdk8:publish",
|
||||
":kotlin-reflect:publish",
|
||||
":kotlin-main-kts:publish"
|
||||
val projectsToPublish = listOf(
|
||||
":prepare:ide-plugin-dependencies:android-extensions-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:allopen-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide",
|
||||
":prepare:ide-plugin-dependencies:js-ir-runtime-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlin-gradle-statistics-for-ide",
|
||||
":prepare:ide-plugin-dependencies:kotlinx-serialization-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:noarg-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:sam-with-receiver-compiler-plugin-for-ide",
|
||||
":prepare:ide-plugin-dependencies:compiler-components-for-jps",
|
||||
":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide",
|
||||
":kotlin-script-runtime",
|
||||
":kotlin-script-util",
|
||||
":kotlin-scripting-common",
|
||||
":kotlin-scripting-jvm",
|
||||
":kotlin-scripting-compiler",
|
||||
":kotlin-scripting-compiler-impl",
|
||||
":kotlin-android-extensions-runtime",
|
||||
":kotlin-stdlib-common",
|
||||
":kotlin-stdlib",
|
||||
":kotlin-stdlib-jdk7",
|
||||
":kotlin-stdlib-jdk8",
|
||||
":kotlin-reflect",
|
||||
":kotlin-main-kts"
|
||||
)
|
||||
|
||||
dependsOn(projectsToPublish.map { "$it:publish" })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ dependencies {
|
||||
testRuntimeOnly(intellijDep()) { includeJars("intellij-deps-fastutil-8.3.1-1") }
|
||||
}
|
||||
Platform[203].orHigher {
|
||||
testRuntimeOnly(intellijDep()) { includeJars("intellij-deps-fastutil-8.3.1-3") }
|
||||
testRuntimeOnly(intellijDep()) { includeJars("intellij-deps-fastutil-8.4.1-4") }
|
||||
}
|
||||
testRuntimeOnly(toolsJar())
|
||||
}
|
||||
|
||||
@@ -223,12 +223,21 @@ internal class KtUltraLightReceiverParameter(
|
||||
method: KtUltraLightMethod
|
||||
) : KtAbstractUltraLightParameterForDeclaration(
|
||||
/** @see org.jetbrains.kotlin.codegen.AsmUtil.getNameForReceiverParameter */
|
||||
name = AsmUtil.getLabeledThisName(method.name, LABELED_THIS_PARAMETER, RECEIVER_PARAMETER_NAME),
|
||||
name = getParameterName(containingDeclaration, method),
|
||||
kotlinOrigin = null,
|
||||
support = support,
|
||||
method = method,
|
||||
containingDeclaration = containingDeclaration
|
||||
) {
|
||||
private companion object {
|
||||
fun getParameterName(containingDeclaration: KtCallableDeclaration, method: KtUltraLightMethod): String {
|
||||
val callableName: String = when {
|
||||
method.kotlinOrigin is KtProperty && containingDeclaration is KtProperty -> containingDeclaration.name ?: method.name
|
||||
else -> method.name
|
||||
}
|
||||
return AsmUtil.getLabeledThisName(callableName, LABELED_THIS_PARAMETER, RECEIVER_PARAMETER_NAME)
|
||||
}
|
||||
}
|
||||
|
||||
override val givenAnnotations: List<KtLightAbstractAnnotation>? =
|
||||
containingDeclaration
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.psi;
|
||||
@@ -70,15 +59,7 @@ public class KtElementImplStub<T extends StubElement<?>> extends StubBasedPsiEle
|
||||
PsiFile file = getContainingFile();
|
||||
if (!(file instanceof KtFile)) {
|
||||
// KtElementImpl.copy() might be the reason for this exception
|
||||
String fileString = "";
|
||||
if (file.isValid()) {
|
||||
try {
|
||||
fileString = " " + file.getText();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// ignore when failed to get file text
|
||||
}
|
||||
}
|
||||
String fileString = file.isValid() ? (" " + file.getText()) : "";
|
||||
// getNode() will fail if getContainingFile() returns not PsiFileImpl instance
|
||||
String nodeString = (file instanceof PsiFileImpl ? (" node = " + getNode()) : "");
|
||||
|
||||
@@ -126,7 +107,7 @@ public class KtElementImplStub<T extends StubElement<?>> extends StubBasedPsiEle
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected <PsiT extends KtElementImplStub<?>, StubT extends StubElement> List<PsiT> getStubOrPsiChildrenAsList(
|
||||
protected <PsiT extends KtElementImplStub<?>, StubT extends StubElement<?>> List<PsiT> getStubOrPsiChildrenAsList(
|
||||
@NotNull KtStubElementType<StubT, PsiT> elementType
|
||||
) {
|
||||
return Arrays.asList(getStubOrPsiChildren(elementType, elementType.getArrayFactory()));
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.psi;
|
||||
|
||||
import com.intellij.extapi.psi.StubBasedPsiElementBase;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PsiFileImpl;
|
||||
import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class KtElementImplStub<T extends StubElement<?>> extends StubBasedPsiElementBase<T>
|
||||
implements KtElement, StubBasedPsiElement<T> {
|
||||
public KtElementImplStub(@NotNull T stub, @NotNull IStubElementType nodeType) {
|
||||
super(stub, nodeType);
|
||||
}
|
||||
|
||||
public KtElementImplStub(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Language getLanguage() {
|
||||
return KotlinLanguage.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getElementType().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof KtVisitor) {
|
||||
accept((KtVisitor) visitor, null);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KtFile getContainingKtFile() {
|
||||
PsiFile file = getContainingFile();
|
||||
if (!(file instanceof KtFile)) {
|
||||
// KtElementImpl.copy() might be the reason for this exception
|
||||
String fileString = "";
|
||||
if (file.isValid()) {
|
||||
try {
|
||||
fileString = " " + file.getText();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// ignore when failed to get file text
|
||||
}
|
||||
}
|
||||
// getNode() will fail if getContainingFile() returns not PsiFileImpl instance
|
||||
String nodeString = (file instanceof PsiFileImpl ? (" node = " + getNode()) : "");
|
||||
|
||||
throw new IllegalStateException("KtElement not inside KtFile: " +
|
||||
file + fileString + " of type " + file.getClass() +
|
||||
" for element " + this + " of type " + this.getClass() + nodeString);
|
||||
}
|
||||
return (KtFile) file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <D> void acceptChildren(@NotNull KtVisitor<Void, D> visitor, D data) {
|
||||
PsiElement child = getFirstChild();
|
||||
while (child != null) {
|
||||
if (child instanceof KtElement) {
|
||||
((KtElement) child).accept(visitor, data);
|
||||
}
|
||||
child = child.getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(@NotNull KtVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitKtElement(this, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() throws IncorrectOperationException {
|
||||
KtElementUtilsKt.deleteSemicolon(this);
|
||||
super.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public PsiReference getReference() {
|
||||
PsiReference[] references = getReferences();
|
||||
if (references.length == 1) return references[0];
|
||||
else return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferences() {
|
||||
return KotlinReferenceProvidersService.getReferencesFromProviders(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected <PsiT extends KtElementImplStub<?>, StubT extends StubElement> List<PsiT> getStubOrPsiChildrenAsList(
|
||||
@NotNull KtStubElementType<StubT, PsiT> elementType
|
||||
) {
|
||||
return Arrays.asList(getStubOrPsiChildren(elementType, elementType.getArrayFactory()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KtElement getPsiOrParent() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getParent() {
|
||||
PsiElement substitute = KtPsiUtilKt.getParentSubstitute(this);
|
||||
return substitute != null ? substitute : super.getParent();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.psi.stubs.elements
|
||||
@@ -30,7 +19,7 @@ class KtAnnotationUseSiteTargetElementType(debugName: String) :
|
||||
debugName, KtAnnotationUseSiteTarget::class.java, KotlinAnnotationUseSiteTargetStub::class.java
|
||||
) {
|
||||
|
||||
override fun createStub(psi: KtAnnotationUseSiteTarget, parentStub: StubElement<PsiElement>): KotlinAnnotationUseSiteTargetStub {
|
||||
override fun createStub(psi: KtAnnotationUseSiteTarget, parentStub: StubElement<out PsiElement>): KotlinAnnotationUseSiteTargetStub {
|
||||
val useSiteTarget = psi.getAnnotationUseSiteTarget().name
|
||||
return KotlinAnnotationUseSiteTargetStubImpl(parentStub, StringRef.fromString(useSiteTarget)!!)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.psi.stubs.elements
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.psi.stubs.StubInputStream
|
||||
import com.intellij.psi.stubs.StubOutputStream
|
||||
import com.intellij.util.io.StringRef
|
||||
import org.jetbrains.kotlin.psi.KtAnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinAnnotationUseSiteTargetStub
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinAnnotationUseSiteTargetStubImpl
|
||||
|
||||
class KtAnnotationUseSiteTargetElementType(debugName: String) :
|
||||
KtStubElementType<KotlinAnnotationUseSiteTargetStub, KtAnnotationUseSiteTarget>(
|
||||
debugName, KtAnnotationUseSiteTarget::class.java, KotlinAnnotationUseSiteTargetStub::class.java
|
||||
) {
|
||||
|
||||
override fun createStub(psi: KtAnnotationUseSiteTarget, parentStub: StubElement<PsiElement>): KotlinAnnotationUseSiteTargetStub {
|
||||
val useSiteTarget = psi.getAnnotationUseSiteTarget().name
|
||||
return KotlinAnnotationUseSiteTargetStubImpl(parentStub, StringRef.fromString(useSiteTarget)!!)
|
||||
}
|
||||
|
||||
override fun serialize(stub: KotlinAnnotationUseSiteTargetStub, dataStream: StubOutputStream) {
|
||||
dataStream.writeName(stub.getUseSiteTarget())
|
||||
}
|
||||
|
||||
override fun deserialize(dataStream: StubInputStream, parentStub: StubElement<PsiElement>): KotlinAnnotationUseSiteTargetStub {
|
||||
val useSiteTarget = dataStream.readName()
|
||||
return KotlinAnnotationUseSiteTargetStubImpl(parentStub, useSiteTarget!!)
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ class KtContractEffectElementType(debugName: String, psiClass: Class<KtContractE
|
||||
return KotlinContractEffectStubImpl(parentStub, this)
|
||||
}
|
||||
|
||||
override fun createStub(psi: KtContractEffect, parentStub: StubElement<PsiElement>?): KotlinContractEffectStub {
|
||||
override fun createStub(psi: KtContractEffect, parentStub: StubElement<*>?): KotlinContractEffectStub {
|
||||
return KotlinContractEffectStubImpl(parentStub, this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.psi.stubs.elements
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.psi.stubs.StubInputStream
|
||||
import com.intellij.psi.stubs.StubOutputStream
|
||||
import org.jetbrains.kotlin.psi.KtContractEffect
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinContractEffectStub
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinContractEffectStubImpl
|
||||
|
||||
class KtContractEffectElementType(debugName: String, psiClass: Class<KtContractEffect>) :
|
||||
KtStubElementType<KotlinContractEffectStub, KtContractEffect>(debugName, psiClass, KotlinContractEffectStub::class.java) {
|
||||
override fun serialize(stub: KotlinContractEffectStub, dataStream: StubOutputStream) {
|
||||
}
|
||||
|
||||
override fun deserialize(dataStream: StubInputStream, parentStub: StubElement<PsiElement>?): KotlinContractEffectStub {
|
||||
return KotlinContractEffectStubImpl(parentStub, this)
|
||||
}
|
||||
|
||||
override fun createStub(psi: KtContractEffect, parentStub: StubElement<PsiElement>?): KotlinContractEffectStub {
|
||||
return KotlinContractEffectStubImpl(parentStub, this)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.psi.stubs.elements
|
||||
@@ -27,7 +16,7 @@ import org.jetbrains.kotlin.psi.stubs.impl.KotlinImportAliasStubImpl
|
||||
|
||||
class KtImportAliasElementType(debugName: String) :
|
||||
KtStubElementType<KotlinImportAliasStub, KtImportAlias>(debugName, KtImportAlias::class.java, KotlinImportAliasStub::class.java) {
|
||||
override fun createStub(psi: KtImportAlias, parentStub: StubElement<PsiElement>?): KotlinImportAliasStub {
|
||||
override fun createStub(psi: KtImportAlias, parentStub: StubElement<out PsiElement>?): KotlinImportAliasStub {
|
||||
return KotlinImportAliasStubImpl(parentStub, StringRef.fromString(psi.name))
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.psi.stubs.elements
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.psi.stubs.StubInputStream
|
||||
import com.intellij.psi.stubs.StubOutputStream
|
||||
import com.intellij.util.io.StringRef
|
||||
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinImportAliasStub
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinImportAliasStubImpl
|
||||
|
||||
class KtImportAliasElementType(debugName: String) :
|
||||
KtStubElementType<KotlinImportAliasStub, KtImportAlias>(debugName, KtImportAlias::class.java, KotlinImportAliasStub::class.java) {
|
||||
override fun createStub(psi: KtImportAlias, parentStub: StubElement<PsiElement>?): KotlinImportAliasStub {
|
||||
return KotlinImportAliasStubImpl(parentStub, StringRef.fromString(psi.name))
|
||||
}
|
||||
|
||||
override fun serialize(stub: KotlinImportAliasStub, dataStream: StubOutputStream) {
|
||||
dataStream.writeName(stub.getName())
|
||||
}
|
||||
|
||||
override fun deserialize(dataStream: StubInputStream, parentStub: StubElement<PsiElement>?): KotlinImportAliasStub {
|
||||
val name = dataStream.readName()
|
||||
return KotlinImportAliasStubImpl(parentStub, name)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.psi.stubs.elements;
|
||||
@@ -36,7 +25,7 @@ public class KtModifierListElementType<T extends KtModifierList> extends KtStubE
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinModifierListStub createStub(@NotNull T psi, StubElement parentStub) {
|
||||
public KotlinModifierListStub createStub(@NotNull T psi, StubElement<?> parentStub) {
|
||||
return new KotlinModifierListStubImpl(parentStub, computeMaskFromModifierList(psi), this);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.psi.stubs.elements;
|
||||
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.stubs.StubInputStream;
|
||||
import com.intellij.psi.stubs.StubOutputStream;
|
||||
import com.intellij.util.io.DataInputOutputUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.psi.KtModifierList;
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinModifierListStub;
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinModifierListStubImpl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.jetbrains.kotlin.psi.stubs.impl.ModifierMaskUtils.computeMaskFromModifierList;
|
||||
|
||||
public class KtModifierListElementType<T extends KtModifierList> extends KtStubElementType<KotlinModifierListStub, T> {
|
||||
public KtModifierListElementType(@NotNull @NonNls String debugName, @NotNull Class<T> psiClass) {
|
||||
super(debugName, psiClass, KotlinModifierListStub.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinModifierListStub createStub(@NotNull T psi, StubElement parentStub) {
|
||||
return new KotlinModifierListStubImpl(parentStub, computeMaskFromModifierList(psi), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(@NotNull KotlinModifierListStub stub, @NotNull StubOutputStream dataStream) throws IOException {
|
||||
long mask = ((KotlinModifierListStubImpl) stub).getMask();
|
||||
DataInputOutputUtil.writeLONG(dataStream, mask);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KotlinModifierListStub deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
|
||||
long mask = DataInputOutputUtil.readLONG(dataStream);
|
||||
return new KotlinModifierListStubImpl(parentStub, mask, this);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.psi.stubs.elements;
|
||||
@@ -34,7 +23,7 @@ public class KtPlaceHolderStubElementType<T extends KtElementImplStub<? extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinPlaceHolderStub<T> createStub(@NotNull T psi, StubElement parentStub) {
|
||||
public KotlinPlaceHolderStub<T> createStub(@NotNull T psi, StubElement<?> parentStub) {
|
||||
return new KotlinPlaceHolderStubImpl<>(parentStub, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.psi.stubs.elements;
|
||||
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.stubs.StubInputStream;
|
||||
import com.intellij.psi.stubs.StubOutputStream;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.psi.KtElementImplStub;
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub;
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinPlaceHolderStubImpl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class KtPlaceHolderStubElementType<T extends KtElementImplStub<? extends StubElement<?>>> extends
|
||||
KtStubElementType<KotlinPlaceHolderStub<T>, T> {
|
||||
public KtPlaceHolderStubElementType(@NotNull @NonNls String debugName, @NotNull Class<T> psiClass) {
|
||||
super(debugName, psiClass, KotlinPlaceHolderStub.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KotlinPlaceHolderStub<T> createStub(@NotNull T psi, StubElement parentStub) {
|
||||
return new KotlinPlaceHolderStubImpl<>(parentStub, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(@NotNull KotlinPlaceHolderStub<T> stub, @NotNull StubOutputStream dataStream) throws IOException {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KotlinPlaceHolderStub<T> deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
|
||||
return new KotlinPlaceHolderStubImpl<>(parentStub, this);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.psi.stubs.elements
|
||||
@@ -30,7 +19,7 @@ class KtScriptElementType(debugName: String) : KtStubElementType<KotlinScriptStu
|
||||
debugName, KtScript::class.java, KotlinScriptStub::class.java
|
||||
) {
|
||||
|
||||
override fun createStub(psi: KtScript, parentStub: StubElement<PsiElement>): KotlinScriptStub {
|
||||
override fun createStub(psi: KtScript, parentStub: StubElement<out PsiElement>): KotlinScriptStub {
|
||||
return KotlinScriptStubImpl(parentStub, StringRef.fromString(psi.fqName.asString()))
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.psi.stubs.elements
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.IndexSink
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.psi.stubs.StubInputStream
|
||||
import com.intellij.psi.stubs.StubOutputStream
|
||||
import com.intellij.util.io.StringRef
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinScriptStub
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinScriptStubImpl
|
||||
|
||||
class KtScriptElementType(debugName: String) : KtStubElementType<KotlinScriptStub, KtScript>(
|
||||
debugName, KtScript::class.java, KotlinScriptStub::class.java
|
||||
) {
|
||||
|
||||
override fun createStub(psi: KtScript, parentStub: StubElement<PsiElement>): KotlinScriptStub {
|
||||
return KotlinScriptStubImpl(parentStub, StringRef.fromString(psi.fqName.asString()))
|
||||
}
|
||||
|
||||
override fun serialize(stub: KotlinScriptStub, dataStream: StubOutputStream) {
|
||||
dataStream.writeName(stub.getFqName().asString())
|
||||
}
|
||||
|
||||
override fun deserialize(dataStream: StubInputStream, parentStub: StubElement<PsiElement>): KotlinScriptStub {
|
||||
val fqName = dataStream.readName()
|
||||
return KotlinScriptStubImpl(parentStub, fqName)
|
||||
}
|
||||
|
||||
|
||||
override fun indexStub(stub: KotlinScriptStub, sink: IndexSink) {
|
||||
StubIndexService.getInstance().indexScript(stub, sink)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.psi.stubs.elements;
|
||||
@@ -36,7 +25,7 @@ import org.jetbrains.kotlin.psi.KtProperty;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
public abstract class KtStubElementType<StubT extends StubElement, PsiT extends KtElementImplStub<?>> extends IStubElementType<StubT, PsiT> {
|
||||
public abstract class KtStubElementType<StubT extends StubElement<?>, PsiT extends KtElementImplStub<?>> extends IStubElementType<StubT, PsiT> {
|
||||
|
||||
@NotNull
|
||||
private final Constructor<PsiT> byNodeConstructor;
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* 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.psi.stubs.elements;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.IndexSink;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IStubFileElementType;
|
||||
import com.intellij.util.ArrayFactory;
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.psi.KtElementImplStub;
|
||||
import org.jetbrains.kotlin.psi.KtFunction;
|
||||
import org.jetbrains.kotlin.psi.KtProperty;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
public abstract class KtStubElementType<StubT extends StubElement, PsiT extends KtElementImplStub<?>> extends IStubElementType<StubT, PsiT> {
|
||||
|
||||
@NotNull
|
||||
private final Constructor<PsiT> byNodeConstructor;
|
||||
@NotNull
|
||||
private final Constructor<PsiT> byStubConstructor;
|
||||
@NotNull
|
||||
private final PsiT[] emptyArray;
|
||||
@NotNull
|
||||
private final ArrayFactory<PsiT> arrayFactory;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public KtStubElementType(@NotNull @NonNls String debugName, @NotNull Class<PsiT> psiClass, @NotNull Class<?> stubClass) {
|
||||
super(debugName, KotlinLanguage.INSTANCE);
|
||||
try {
|
||||
byNodeConstructor = psiClass.getConstructor(ASTNode.class);
|
||||
byStubConstructor = psiClass.getConstructor(stubClass);
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("Stub element type declaration for " + psiClass.getSimpleName() + " is missing required constructors",e);
|
||||
}
|
||||
emptyArray = (PsiT[]) Array.newInstance(psiClass, 0);
|
||||
arrayFactory = count -> {
|
||||
if (count == 0) {
|
||||
return emptyArray;
|
||||
}
|
||||
return (PsiT[]) Array.newInstance(psiClass, count);
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiT createPsiFromAst(@NotNull ASTNode node) {
|
||||
return ReflectionUtil.createInstance(byNodeConstructor, node);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiT createPsi(@NotNull StubT stub) {
|
||||
return ReflectionUtil.createInstance(byStubConstructor, stub);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getExternalId() {
|
||||
return "kotlin." + toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldCreateStub(ASTNode node) {
|
||||
PsiElement psi = node.getPsi();
|
||||
if (psi instanceof KtClassOrObject || psi instanceof KtFunction) {
|
||||
return true;
|
||||
}
|
||||
if (psi instanceof KtProperty) {
|
||||
return !((KtProperty) psi).isLocal();
|
||||
}
|
||||
return createStubDependingOnParent(node);
|
||||
}
|
||||
|
||||
private static boolean createStubDependingOnParent(ASTNode node) {
|
||||
ASTNode parent = node.getTreeParent();
|
||||
IElementType parentType = parent.getElementType();
|
||||
if (parentType instanceof IStubElementType) {
|
||||
return ((IStubElementType) parentType).shouldCreateStub(parent);
|
||||
}
|
||||
if (parentType instanceof IStubFileElementType) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void indexStub(@NotNull StubT stub, @NotNull IndexSink sink) {
|
||||
// do not force inheritors to implement this method
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ArrayFactory<PsiT> getArrayFactory() {
|
||||
return arrayFactory;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.psi.stubs.impl.KotlinValueArgumentStubImpl
|
||||
class KtValueArgumentElementType<T : KtValueArgument>(debugName: String, psiClass: Class<T>) :
|
||||
KtStubElementType<KotlinValueArgumentStub<T>, T>(debugName, psiClass, KotlinValueArgumentStub::class.java) {
|
||||
|
||||
override fun createStub(psi: T, parentStub: StubElement<PsiElement>?): KotlinValueArgumentStub<T> {
|
||||
override fun createStub(psi: T, parentStub: StubElement<out PsiElement>?): KotlinValueArgumentStub<T> {
|
||||
return KotlinValueArgumentStubImpl(parentStub, this, psi.isSpread)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.psi.stubs.elements
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.psi.stubs.StubInputStream
|
||||
import com.intellij.psi.stubs.StubOutputStream
|
||||
import org.jetbrains.kotlin.psi.KtValueArgument
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinValueArgumentStub
|
||||
import org.jetbrains.kotlin.psi.stubs.impl.KotlinValueArgumentStubImpl
|
||||
|
||||
class KtValueArgumentElementType<T : KtValueArgument>(debugName: String, psiClass: Class<T>) :
|
||||
KtStubElementType<KotlinValueArgumentStub<T>, T>(debugName, psiClass, KotlinValueArgumentStub::class.java) {
|
||||
|
||||
override fun createStub(psi: T, parentStub: StubElement<PsiElement>?): KotlinValueArgumentStub<T> {
|
||||
return KotlinValueArgumentStubImpl(parentStub, this, psi.isSpread)
|
||||
}
|
||||
|
||||
override fun serialize(stub: KotlinValueArgumentStub<T>, dataStream: StubOutputStream) {
|
||||
dataStream.writeBoolean(stub.isSpread())
|
||||
}
|
||||
|
||||
override fun deserialize(dataStream: StubInputStream, parentStub: StubElement<PsiElement>?): KotlinValueArgumentStub<T> {
|
||||
val isSpread = dataStream.readBoolean()
|
||||
return KotlinValueArgumentStubImpl(parentStub, this, isSpread)
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.psi.stubs.impl
|
||||
@@ -24,7 +13,7 @@ import org.jetbrains.kotlin.psi.stubs.KotlinImportAliasStub
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
|
||||
class KotlinImportAliasStubImpl(
|
||||
parent: StubElement<PsiElement>?,
|
||||
parent: StubElement<out PsiElement>?,
|
||||
private val name: StringRef?
|
||||
) : KotlinStubBaseImpl<KtImportAlias>(parent, KtStubElementTypes.IMPORT_ALIAS), KotlinImportAliasStub {
|
||||
override fun getName(): String? = StringRef.toString(name)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.psi.stubs.impl
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.util.io.StringRef
|
||||
import org.jetbrains.kotlin.psi.KtImportAlias
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinImportAliasStub
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
|
||||
class KotlinImportAliasStubImpl(
|
||||
parent: StubElement<PsiElement>?,
|
||||
private val name: StringRef?
|
||||
) : KotlinStubBaseImpl<KtImportAlias>(parent, KtStubElementTypes.IMPORT_ALIAS), KotlinImportAliasStub {
|
||||
override fun getName(): String? = StringRef.toString(name)
|
||||
}
|
||||
@@ -255,7 +255,7 @@ class BinaryJavaClass(
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitPermittedSubtypeExperimental(permittedSubtype: String?) {
|
||||
permittedTypes.addIfNotNull(permittedSubtype?.convertInternalNameToClassifierType())
|
||||
override fun visitPermittedSubclass(permittedSubclass: String?) {
|
||||
permittedTypes.addIfNotNull(permittedSubclass?.convertInternalNameToClassifierType())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ dependencies {
|
||||
testRuntimeOnly(intellijDep()) { includeJars("intellij-deps-fastutil-8.3.1-1") }
|
||||
}
|
||||
Platform[203].orHigher {
|
||||
testRuntimeOnly(intellijDep()) { includeJars("intellij-deps-fastutil-8.3.1-3") }
|
||||
testRuntimeOnly(intellijDep()) { includeJars("intellij-deps-fastutil-8.4.1-4") }
|
||||
}
|
||||
testRuntimeOnly(toolsJar())
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ dependencies {
|
||||
testCompile(intellijDep()) { includeJars("intellij-deps-fastutil-8.3.1-1") }
|
||||
}
|
||||
Platform[203].orHigher {
|
||||
testCompile(intellijDep()) { includeJars("intellij-deps-fastutil-8.3.1-3") }
|
||||
testCompile(intellijDep()) { includeJars("intellij-deps-fastutil-8.4.1-4") }
|
||||
}
|
||||
testCompile(intellijDep()) {
|
||||
includeJars(
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* Copyright 2010-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.
|
||||
* 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.test.testFramework;
|
||||
@@ -19,14 +8,15 @@ package org.jetbrains.kotlin.test.testFramework;
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory;
|
||||
import com.intellij.diagnostic.PerformanceWatcher;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.Application;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.JDOMUtil;
|
||||
@@ -347,7 +337,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
})
|
||||
.append(() -> {
|
||||
currentCodeStyleSettings.getIndentOptions(JavaFileType.INSTANCE);
|
||||
currentCodeStyleSettings.getIndentOptions(StdFileTypes.JAVA);
|
||||
try {
|
||||
checkCodeStyleSettingsEqual(oldCodeStyleSettings, currentCodeStyleSettings);
|
||||
}
|
||||
@@ -501,7 +491,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
/**
|
||||
* If you want a more shorter name than runInEdtAndWait.
|
||||
*/
|
||||
protected void edt(@NotNull ThrowableRunnable<Throwable> runnable) {
|
||||
protected void edt(@NotNull ThrowableRunnable<Throwable> runnable) throws Throwable {
|
||||
EdtTestUtil.runInEdtAndWait(runnable);
|
||||
}
|
||||
|
||||
@@ -911,7 +901,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
}
|
||||
String expected = StringUtil.convertLineSeparators(trimBeforeComparing ? fileText.trim() : fileText);
|
||||
String actual = StringUtil.convertLineSeparators(trimBeforeComparing ? actualText.trim() : actualText);
|
||||
if (!Objects.equals(expected, actual)) {
|
||||
if (!Comparing.equal(expected, actual)) {
|
||||
throw new FileComparisonFailure(messageProducer == null ? null : messageProducer.get(), expected, actual, filePath);
|
||||
}
|
||||
}
|
||||
@@ -1144,7 +1134,7 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
return UIUtil.invokeAndWaitIfNeeded(() -> LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file));
|
||||
}
|
||||
|
||||
public static void waitForAppLeakingThreads(long timeout, @NotNull TimeUnit timeUnit) {
|
||||
public static void waitForAppLeakingThreads(long timeout, @NotNull TimeUnit timeUnit) throws Exception {
|
||||
EdtTestUtil.runInEdtAndWait(() -> {
|
||||
Application app = ApplicationManager.getApplication();
|
||||
if (app != null && !app.isDisposed()) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx2200m -Dfile.encoding=UTF-8 -Dorg.gradle.internal.publish.checksums.insecure=true
|
||||
|
||||
org.gradle.parallel=true
|
||||
org.gradle.caching=true
|
||||
#org.gradle.caching=true
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
defaultSnapshotVersion=1.5.255-SNAPSHOT
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
versions.intellijSdk=202.7660.26
|
||||
versions.intellijSdk=203.6682.168
|
||||
versions.idea.NodeJS=193.6494.7
|
||||
versions.jar.asm-all=8.0.1
|
||||
versions.jar.asm-all=9.0
|
||||
versions.jar.guava=29.0-jre
|
||||
versions.jar.groovy=2.5.11
|
||||
versions.jar.groovy-xml=2.5.11
|
||||
|
||||
20
gradle/versions.properties.202
Normal file
20
gradle/versions.properties.202
Normal file
@@ -0,0 +1,20 @@
|
||||
versions.intellijSdk=202.7660.26
|
||||
versions.idea.NodeJS=193.6494.7
|
||||
versions.jar.asm-all=8.0.1
|
||||
versions.jar.guava=29.0-jre
|
||||
versions.jar.groovy=2.5.11
|
||||
versions.jar.groovy-xml=2.5.11
|
||||
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,6 +1,6 @@
|
||||
versions.intellijSdk=203-SNAPSHOT
|
||||
versions.intellijSdk=203.6682.168
|
||||
versions.idea.NodeJS=193.6494.7
|
||||
versions.jar.asm-all=8.0.1
|
||||
versions.jar.asm-all=9.0
|
||||
versions.jar.guava=29.0-jre
|
||||
versions.jar.groovy=2.5.11
|
||||
versions.jar.groovy-xml=2.5.11
|
||||
@@ -16,3 +16,5 @@ 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
|
||||
|
||||
@@ -100,7 +100,7 @@ dependencies {
|
||||
|
||||
implementation(commonDep("org.jetbrains.intellij.deps.completion", "completion-ranking-kotlin"))
|
||||
Ide.IJ {
|
||||
implementation(intellijPluginDep("stats-collector"))
|
||||
// implementation(intellijPluginDep("stats-collector"))
|
||||
}
|
||||
|
||||
compileOnly(commonDep("org.jetbrains", "markdown"))
|
||||
@@ -201,6 +201,9 @@ dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
tasks.named<Copy>("processResources") {
|
||||
val currentIde = IdeVersionConfigurator.currentIde
|
||||
val pluginPatchNumber = findProperty("pluginPatchNumber") as String? ?: "1"
|
||||
|
||||
@@ -16,3 +16,5 @@ sourceSets {
|
||||
"test" {}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -18,6 +18,9 @@ sourceSets {
|
||||
"test" {}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
sourcesJar()
|
||||
|
||||
javadocJar()
|
||||
|
||||
@@ -86,6 +86,9 @@ sourceSets {
|
||||
"test" { }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
projectTest(parallel = true) {
|
||||
workingDir = rootDir
|
||||
useAndroidSdk()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -9,7 +9,8 @@ import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.completion.CompletionTestCase;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
|
||||
@@ -18,20 +19,18 @@ abstract public class KotlinCompletionTestCase extends CompletionTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), KtTestUtil.getHomeDirectory());
|
||||
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = new String[]{"excludedPackage", "somePackage.ExcludedClass"};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
//noinspection Convert2MethodRef
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTest());
|
||||
protected void runTestRunnable(@NotNull ThrowableRunnable<Throwable> testRunnable) throws Throwable {
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTestRunnable(testRunnable));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.completion.test;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.completion.CompletionTestCase;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
|
||||
@WithMutedInDatabaseRunTest
|
||||
abstract public class KotlinCompletionTestCase extends CompletionTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = new String[]{"excludedPackage", "somePackage.ExcludedClass"};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
CodeInsightSettings.getInstance().EXCLUDED_PACKAGES = ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
//noinspection Convert2MethodRef
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTest());
|
||||
}
|
||||
}
|
||||
@@ -44,3 +44,6 @@ sourceSets {
|
||||
}
|
||||
"test" {}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -37,6 +37,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
projectTest(parallel = true) {
|
||||
dependsOn(":dist")
|
||||
workingDir = project.rootDir
|
||||
|
||||
@@ -34,6 +34,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
projectTest(parallel = true) {
|
||||
dependsOn(":dist")
|
||||
workingDir = rootDir
|
||||
|
||||
@@ -44,6 +44,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
projectTest {
|
||||
dependsOn(":dist")
|
||||
workingDir = rootDir
|
||||
|
||||
@@ -45,6 +45,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
projectTest {
|
||||
dependsOn(":dist")
|
||||
workingDir = rootDir
|
||||
|
||||
@@ -35,6 +35,9 @@ sourceSets {
|
||||
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
testsJar()
|
||||
|
||||
projectTest {
|
||||
|
||||
@@ -14,3 +14,6 @@ sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -85,6 +85,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
testsJar()
|
||||
|
||||
projectTest(parallel = true) {
|
||||
|
||||
@@ -95,6 +95,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
testsJar()
|
||||
|
||||
projectTest(parallel = false) {
|
||||
|
||||
@@ -14,4 +14,7 @@ dependencies {
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { none() }
|
||||
}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -21,4 +21,7 @@ sourceSets {
|
||||
"test" {}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
runtimeJar()
|
||||
|
||||
@@ -32,6 +32,9 @@ sourceSets {
|
||||
"test" { none() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
configureFormInstrumentation()
|
||||
|
||||
runtimeJar()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.scratch.ui
|
||||
|
||||
import com.intellij.execution.ui.ConfigurationModuleSelector
|
||||
import com.intellij.core.JavaPsiBundle
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup
|
||||
import com.intellij.openapi.actionSystem.Presentation
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.caches.project.productionSourceInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.testSourceInfo
|
||||
import org.jetbrains.kotlin.idea.scratch.ScratchFile
|
||||
import org.jetbrains.kotlin.idea.scratch.isKotlinWorksheet
|
||||
import java.util.function.Supplier
|
||||
import javax.swing.JComponent
|
||||
|
||||
class ModulesComboBoxAction(private val scratchFile: ScratchFile) :
|
||||
@@ -28,7 +29,7 @@ class ModulesComboBoxAction(private val scratchFile: ScratchFile) :
|
||||
{
|
||||
override fun createPopupActionGroup(button: JComponent): DefaultActionGroup {
|
||||
val actionGroup = DefaultActionGroup()
|
||||
actionGroup.add(ModuleIsNotSelectedAction(ConfigurationModuleSelector.NO_MODULE_TEXT))
|
||||
actionGroup.add(ModuleIsNotSelectedAction(JavaPsiBundle.messagePointer("list.item.no.module")))
|
||||
|
||||
val modules = ModuleManager.getInstance(scratchFile.project).modules.filter {
|
||||
it.productionSourceInfo() != null || it.testSourceInfo() != null
|
||||
@@ -55,7 +56,7 @@ class ModulesComboBoxAction(private val scratchFile: ScratchFile) :
|
||||
|
||||
e.presentation.apply {
|
||||
icon = selectedModule?.let { ModuleType.get(it).icon }
|
||||
text = selectedModule?.name ?: ConfigurationModuleSelector.NO_MODULE_TEXT
|
||||
text = selectedModule?.name ?: JavaPsiBundle.message("list.item.no.module")
|
||||
}
|
||||
|
||||
e.presentation.isVisible = isModuleSelectorVisible()
|
||||
@@ -66,7 +67,7 @@ class ModulesComboBoxAction(private val scratchFile: ScratchFile) :
|
||||
return !scratchFile.file.isKotlinWorksheet
|
||||
}
|
||||
|
||||
private inner class ModuleIsNotSelectedAction(placeholder: String) : DumbAwareAction(placeholder) {
|
||||
private inner class ModuleIsNotSelectedAction(placeholder: Supplier<String>) : DumbAwareAction(placeholder) {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
scratchFile.setModule(null)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.ui
|
||||
|
||||
import com.intellij.execution.ui.ConfigurationModuleSelector
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup
|
||||
import com.intellij.openapi.actionSystem.Presentation
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.module.ModuleType
|
||||
import com.intellij.openapi.project.DumbAwareAction
|
||||
import com.intellij.openapi.vcs.changes.committed.LabeledComboBoxAction
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.idea.KotlinJvmBundle
|
||||
import org.jetbrains.kotlin.idea.caches.project.productionSourceInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.testSourceInfo
|
||||
import org.jetbrains.kotlin.idea.scratch.ScratchFile
|
||||
import org.jetbrains.kotlin.idea.scratch.isKotlinWorksheet
|
||||
import javax.swing.JComponent
|
||||
|
||||
class ModulesComboBoxAction(private val scratchFile: ScratchFile) :
|
||||
LabeledComboBoxAction(KotlinJvmBundle.message("scratch.module.combobox"))
|
||||
{
|
||||
override fun createPopupActionGroup(button: JComponent): DefaultActionGroup {
|
||||
val actionGroup = DefaultActionGroup()
|
||||
actionGroup.add(ModuleIsNotSelectedAction(ConfigurationModuleSelector.NO_MODULE_TEXT))
|
||||
|
||||
val modules = ModuleManager.getInstance(scratchFile.project).modules.filter {
|
||||
it.productionSourceInfo() != null || it.testSourceInfo() != null
|
||||
}
|
||||
|
||||
actionGroup.addAll(modules.map { SelectModuleAction(it) })
|
||||
|
||||
return actionGroup
|
||||
}
|
||||
|
||||
/**
|
||||
* By default this action uses big font for label, so we have to decrease it
|
||||
* to make it look the same as in [CheckboxAction].
|
||||
*/
|
||||
override fun createCustomComponent(presentation: Presentation, place: String): JComponent {
|
||||
val customComponent = super.createCustomComponent(presentation, place)
|
||||
customComponent.components.forEach { it.font = UIUtil.getFont(UIUtil.FontSize.SMALL, it.font) }
|
||||
return customComponent
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
super.update(e)
|
||||
val selectedModule = scratchFile.module?.takeIf { !it.isDisposed }
|
||||
|
||||
e.presentation.apply {
|
||||
icon = selectedModule?.let { ModuleType.get(it).icon }
|
||||
text = selectedModule?.name ?: ConfigurationModuleSelector.NO_MODULE_TEXT
|
||||
}
|
||||
|
||||
e.presentation.isVisible = isModuleSelectorVisible()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun isModuleSelectorVisible(): Boolean {
|
||||
return !scratchFile.file.isKotlinWorksheet
|
||||
}
|
||||
|
||||
private inner class ModuleIsNotSelectedAction(placeholder: String) : DumbAwareAction(placeholder) {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
scratchFile.setModule(null)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class SelectModuleAction(private val module: Module) :
|
||||
DumbAwareAction(module.name, null, ModuleType.get(module).icon) {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
scratchFile.setModule(module)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,9 @@ if (Ide.IJ()) {
|
||||
}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
testsJar()
|
||||
|
||||
projectTest(parallel = true) {
|
||||
|
||||
@@ -42,7 +42,10 @@ import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.execution.*;
|
||||
import org.jetbrains.idea.maven.execution.MavenExecutor;
|
||||
import org.jetbrains.idea.maven.execution.MavenRunnerParameters;
|
||||
import org.jetbrains.idea.maven.execution.MavenRunnerSettings;
|
||||
import org.jetbrains.idea.maven.execution.SoutMavenConsole;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifact;
|
||||
import org.jetbrains.idea.maven.model.MavenExplicitProfiles;
|
||||
import org.jetbrains.idea.maven.project.*;
|
||||
@@ -68,12 +71,12 @@ public abstract class MavenImportingTestCase extends MavenTestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
VfsRootAccess.allowRootAccess(PathManager.getConfigPath());
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), PathManager.getConfigPath());
|
||||
super.setUp();
|
||||
myGlobalSettingsFile =
|
||||
MavenWorkspaceSettingsComponent.getInstance(myProject).getSettings().generalSettings.getEffectiveGlobalSettingsIoFile();
|
||||
if (myGlobalSettingsFile != null) {
|
||||
VfsRootAccess.allowRootAccess(myGlobalSettingsFile.getAbsolutePath());
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), myGlobalSettingsFile.getAbsolutePath());
|
||||
}
|
||||
sdkCreationChecker = new KotlinSdkCreationChecker();
|
||||
}
|
||||
@@ -89,10 +92,6 @@ public abstract class MavenImportingTestCase extends MavenTestCase {
|
||||
protected void tearDown() throws Exception {
|
||||
try {
|
||||
JavaAwareProjectJdkTableImpl.removeInternalJdkInTests();
|
||||
if (myGlobalSettingsFile != null) {
|
||||
VfsRootAccess.disallowRootAccess(myGlobalSettingsFile.getAbsolutePath());
|
||||
}
|
||||
VfsRootAccess.disallowRootAccess(PathManager.getConfigPath());
|
||||
Messages.setTestDialog(TestDialog.DEFAULT);
|
||||
removeFromLocalRepository("test");
|
||||
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory().toFile());
|
||||
|
||||
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
* 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.maven;
|
||||
|
||||
import com.intellij.compiler.server.BuildManager;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.TestDialog;
|
||||
import com.intellij.openapi.util.AsyncResult;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.execution.*;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifact;
|
||||
import org.jetbrains.idea.maven.model.MavenExplicitProfiles;
|
||||
import org.jetbrains.idea.maven.project.*;
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootType;
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootProperties;
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType;
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
|
||||
import org.jetbrains.kotlin.idea.test.KotlinSdkCreationChecker;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@WithMutedInDatabaseRunTest
|
||||
public abstract class MavenImportingTestCase extends MavenTestCase {
|
||||
protected MavenProjectsTree myProjectsTree;
|
||||
protected MavenProjectsManager myProjectsManager;
|
||||
private File myGlobalSettingsFile;
|
||||
protected KotlinSdkCreationChecker sdkCreationChecker;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
VfsRootAccess.allowRootAccess(PathManager.getConfigPath());
|
||||
super.setUp();
|
||||
myGlobalSettingsFile =
|
||||
MavenWorkspaceSettingsComponent.getInstance(myProject).getSettings().generalSettings.getEffectiveGlobalSettingsIoFile();
|
||||
if (myGlobalSettingsFile != null) {
|
||||
VfsRootAccess.allowRootAccess(myGlobalSettingsFile.getAbsolutePath());
|
||||
}
|
||||
sdkCreationChecker = new KotlinSdkCreationChecker();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpInWriteAction() throws Exception {
|
||||
super.setUpInWriteAction();
|
||||
myProjectsManager = MavenProjectsManager.getInstance(myProject);
|
||||
removeFromLocalRepository("test");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
try {
|
||||
JavaAwareProjectJdkTableImpl.removeInternalJdkInTests();
|
||||
if (myGlobalSettingsFile != null) {
|
||||
VfsRootAccess.disallowRootAccess(myGlobalSettingsFile.getAbsolutePath());
|
||||
}
|
||||
VfsRootAccess.disallowRootAccess(PathManager.getConfigPath());
|
||||
Messages.setTestDialog(TestDialog.DEFAULT);
|
||||
removeFromLocalRepository("test");
|
||||
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory().toFile());
|
||||
sdkCreationChecker.removeNewKotlinSdk();
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTest());
|
||||
}
|
||||
|
||||
protected void assertModules(String... expectedNames) {
|
||||
Module[] actual = ModuleManager.getInstance(myProject).getModules();
|
||||
List<String> actualNames = new ArrayList<String>();
|
||||
|
||||
for (Module m : actual) {
|
||||
actualNames.add(m.getName());
|
||||
}
|
||||
|
||||
assertUnorderedElementsAreEqual(actualNames, expectedNames);
|
||||
}
|
||||
|
||||
protected void assertContentRoots(String moduleName, String... expectedRoots) {
|
||||
List<String> actual = new ArrayList<String>();
|
||||
for (ContentEntry e : getContentRoots(moduleName)) {
|
||||
actual.add(e.getUrl());
|
||||
}
|
||||
|
||||
for (int i = 0; i < expectedRoots.length; i++) {
|
||||
expectedRoots[i] = VfsUtil.pathToUrl(expectedRoots[i]);
|
||||
}
|
||||
|
||||
assertUnorderedPathsAreEqual(actual, Arrays.asList(expectedRoots));
|
||||
}
|
||||
|
||||
protected void assertSources(String moduleName, String... expectedSources) {
|
||||
assertContentFolders(moduleName, JavaSourceRootType.SOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertGeneratedSources(String moduleName, String... expectedSources) {
|
||||
ContentEntry contentRoot = getContentRoot(moduleName);
|
||||
List<ContentFolder> folders = new ArrayList<ContentFolder>();
|
||||
for (SourceFolder folder : contentRoot.getSourceFolders(JavaSourceRootType.SOURCE)) {
|
||||
JavaSourceRootProperties properties = folder.getJpsElement().getProperties(JavaSourceRootType.SOURCE);
|
||||
assertNotNull(properties);
|
||||
if (properties.isForGeneratedSources()) {
|
||||
folders.add(folder);
|
||||
}
|
||||
}
|
||||
doAssertContentFolders(contentRoot, folders, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertResources(String moduleName, String... expectedSources) {
|
||||
assertContentFolders(moduleName, JavaResourceRootType.RESOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertTestSources(String moduleName, String... expectedSources) {
|
||||
assertContentFolders(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertTestResources(String moduleName, String... expectedSources) {
|
||||
assertContentFolders(moduleName, JavaResourceRootType.TEST_RESOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertExcludes(String moduleName, String... expectedExcludes) {
|
||||
ContentEntry contentRoot = getContentRoot(moduleName);
|
||||
doAssertContentFolders(contentRoot, Arrays.asList(contentRoot.getExcludeFolders()), expectedExcludes);
|
||||
}
|
||||
|
||||
protected void assertContentRootExcludes(String moduleName, String contentRoot, String... expectedExcudes) {
|
||||
ContentEntry root = getContentRoot(moduleName, contentRoot);
|
||||
doAssertContentFolders(root, Arrays.asList(root.getExcludeFolders()), expectedExcudes);
|
||||
}
|
||||
|
||||
protected void assertContentFolders(String moduleName, @NotNull JpsModuleSourceRootType<?> rootType, String... expected) {
|
||||
ContentEntry contentRoot = getContentRoot(moduleName);
|
||||
doAssertContentFolders(contentRoot, contentRoot.getSourceFolders(rootType), expected);
|
||||
}
|
||||
|
||||
private static void doAssertContentFolders(ContentEntry e, final List<? extends ContentFolder> folders, String... expected) {
|
||||
List<String> actual = new ArrayList<String>();
|
||||
for (ContentFolder f : folders) {
|
||||
String rootUrl = e.getUrl();
|
||||
String folderUrl = f.getUrl();
|
||||
|
||||
if (folderUrl.startsWith(rootUrl)) {
|
||||
int length = rootUrl.length() + 1;
|
||||
folderUrl = folderUrl.substring(Math.min(length, folderUrl.length()));
|
||||
}
|
||||
|
||||
actual.add(folderUrl);
|
||||
}
|
||||
|
||||
assertOrderedElementsAreEqual(actual, Arrays.asList(expected));
|
||||
}
|
||||
|
||||
protected void assertModuleOutput(String moduleName, String output, String testOutput) {
|
||||
CompilerModuleExtension e = getCompilerExtension(moduleName);
|
||||
|
||||
assertFalse(e.isCompilerOutputPathInherited());
|
||||
assertEquals(output, getAbsolutePath(e.getCompilerOutputUrl()));
|
||||
assertEquals(testOutput, getAbsolutePath(e.getCompilerOutputUrlForTests()));
|
||||
}
|
||||
|
||||
private static String getAbsolutePath(String path) {
|
||||
path = VfsUtil.urlToPath(path);
|
||||
path = PathUtil.getCanonicalPath(path);
|
||||
return FileUtil.toSystemIndependentName(path);
|
||||
}
|
||||
|
||||
protected void assertProjectOutput(String module) {
|
||||
assertTrue(getCompilerExtension(module).isCompilerOutputPathInherited());
|
||||
}
|
||||
|
||||
protected CompilerModuleExtension getCompilerExtension(String module) {
|
||||
ModuleRootManager m = getRootManager(module);
|
||||
return CompilerModuleExtension.getInstance(m.getModule());
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName, String depName) {
|
||||
assertModuleLibDep(moduleName, depName, null);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName, String depName, String classesPath) {
|
||||
assertModuleLibDep(moduleName, depName, classesPath, null, null);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName, String depName, String classesPath, String sourcePath, String javadocPath) {
|
||||
LibraryOrderEntry lib = getModuleLibDep(moduleName, depName);
|
||||
|
||||
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPath == null ? null : Collections.singletonList(classesPath));
|
||||
assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePath == null ? null : Collections.singletonList(sourcePath));
|
||||
assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(),
|
||||
javadocPath == null ? null : Collections.singletonList(javadocPath));
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(
|
||||
String moduleName,
|
||||
String depName,
|
||||
List<String> classesPaths,
|
||||
List<String> sourcePaths,
|
||||
List<String> javadocPaths
|
||||
) {
|
||||
LibraryOrderEntry lib = getModuleLibDep(moduleName, depName);
|
||||
|
||||
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPaths);
|
||||
assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePaths);
|
||||
assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(), javadocPaths);
|
||||
}
|
||||
|
||||
private static void assertModuleLibDepPath(LibraryOrderEntry lib, OrderRootType type, List<String> paths) {
|
||||
if (paths == null) return;
|
||||
assertUnorderedPathsAreEqual(Arrays.asList(lib.getRootUrls(type)), paths);
|
||||
// also check the library because it may contain slight different set of urls (e.g. with duplicates)
|
||||
assertUnorderedPathsAreEqual(Arrays.asList(lib.getLibrary().getUrls(type)), paths);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDepScope(String moduleName, String depName, DependencyScope scope) {
|
||||
LibraryOrderEntry dep = getModuleLibDep(moduleName, depName);
|
||||
assertEquals(scope, dep.getScope());
|
||||
}
|
||||
|
||||
private LibraryOrderEntry getModuleLibDep(String moduleName, String depName) {
|
||||
return getModuleDep(moduleName, depName, LibraryOrderEntry.class);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDeps(String moduleName, String... expectedDeps) {
|
||||
assertModuleDeps(moduleName, LibraryOrderEntry.class, expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertExportedDeps(String moduleName, String... expectedDeps) {
|
||||
final List<String> actual = new ArrayList<String>();
|
||||
|
||||
getRootManager(moduleName).orderEntries().withoutSdk().withoutModuleSourceEntries().exportedOnly()
|
||||
.process(new RootPolicy<Object>() {
|
||||
@Override
|
||||
public Object visitModuleOrderEntry(ModuleOrderEntry e, Object value) {
|
||||
actual.add(e.getModuleName());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitLibraryOrderEntry(LibraryOrderEntry e, Object value) {
|
||||
actual.add(e.getLibraryName());
|
||||
return null;
|
||||
}
|
||||
}, null);
|
||||
|
||||
assertOrderedElementsAreEqual(actual, expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertModuleModuleDeps(String moduleName, String... expectedDeps) {
|
||||
assertModuleDeps(moduleName, ModuleOrderEntry.class, expectedDeps);
|
||||
}
|
||||
|
||||
private void assertModuleDeps(String moduleName, Class clazz, String... expectedDeps) {
|
||||
assertOrderedElementsAreEqual(collectModuleDepsNames(moduleName, clazz), expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertModuleModuleDepScope(String moduleName, String depName, DependencyScope scope) {
|
||||
ModuleOrderEntry dep = getModuleModuleDep(moduleName, depName);
|
||||
assertEquals(scope, dep.getScope());
|
||||
}
|
||||
|
||||
private ModuleOrderEntry getModuleModuleDep(String moduleName, String depName) {
|
||||
return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
|
||||
}
|
||||
|
||||
private List<String> collectModuleDepsNames(String moduleName, Class clazz) {
|
||||
List<String> actual = new ArrayList<String>();
|
||||
|
||||
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
|
||||
if (clazz.isInstance(e)) {
|
||||
actual.add(e.getPresentableName());
|
||||
}
|
||||
}
|
||||
return actual;
|
||||
}
|
||||
|
||||
private <T> T getModuleDep(String moduleName, String depName, Class<T> clazz) {
|
||||
T dep = null;
|
||||
|
||||
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
|
||||
if (clazz.isInstance(e) && e.getPresentableName().equals(depName)) {
|
||||
dep = (T) e;
|
||||
}
|
||||
}
|
||||
assertNotNull("Dependency not found: " + depName
|
||||
+ "\namong: " + collectModuleDepsNames(moduleName, clazz),
|
||||
dep);
|
||||
return dep;
|
||||
}
|
||||
|
||||
public void assertProjectLibraries(String... expectedNames) {
|
||||
List<String> actualNames = new ArrayList<String>();
|
||||
for (Library each : ProjectLibraryTable.getInstance(myProject).getLibraries()) {
|
||||
String name = each.getName();
|
||||
actualNames.add(name == null ? "<unnamed>" : name);
|
||||
}
|
||||
assertUnorderedElementsAreEqual(actualNames, expectedNames);
|
||||
}
|
||||
|
||||
protected void assertModuleGroupPath(String moduleName, String... expected) {
|
||||
String[] path = ModuleManager.getInstance(myProject).getModuleGroupPath(getModule(moduleName));
|
||||
|
||||
if (expected.length == 0) {
|
||||
assertNull(path);
|
||||
}
|
||||
else {
|
||||
assertNotNull(path);
|
||||
assertOrderedElementsAreEqual(Arrays.asList(path), expected);
|
||||
}
|
||||
}
|
||||
|
||||
protected Module getModule(final String name) {
|
||||
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
|
||||
assertNotNull("Module " + name + " not found", m);
|
||||
return m;
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private ContentEntry getContentRoot(String moduleName) {
|
||||
ContentEntry[] ee = getContentRoots(moduleName);
|
||||
List<String> roots = new ArrayList<String>();
|
||||
for (ContentEntry e : ee) {
|
||||
roots.add(e.getUrl());
|
||||
}
|
||||
|
||||
String message = "Several content roots found: [" + StringUtil.join(roots, ", ") + "]";
|
||||
assertEquals(message, 1, ee.length);
|
||||
|
||||
return ee[0];
|
||||
}
|
||||
|
||||
private ContentEntry getContentRoot(String moduleName, String path) {
|
||||
for (ContentEntry e : getContentRoots(moduleName)) {
|
||||
if (e.getUrl().equals(VfsUtil.pathToUrl(path))) return e;
|
||||
}
|
||||
throw new AssertionError("content root not found");
|
||||
}
|
||||
|
||||
public ContentEntry[] getContentRoots(String moduleName) {
|
||||
return getRootManager(moduleName).getContentEntries();
|
||||
}
|
||||
|
||||
private ModuleRootManager getRootManager(String module) {
|
||||
return ModuleRootManager.getInstance(getModule(module));
|
||||
}
|
||||
|
||||
protected void importProject(@NonNls String xml) throws IOException {
|
||||
createProjectPom(xml);
|
||||
importProject();
|
||||
}
|
||||
|
||||
protected void importProject() {
|
||||
importProjectWithProfiles();
|
||||
}
|
||||
|
||||
protected void importProjectWithProfiles(String... profiles) {
|
||||
doImportProjects(Collections.singletonList(myProjectPom), profiles);
|
||||
}
|
||||
|
||||
protected void importProjects(VirtualFile... files) {
|
||||
doImportProjects(Arrays.asList(files));
|
||||
}
|
||||
|
||||
private void doImportProjects(List<VirtualFile> files, String... profiles) {
|
||||
initProjectsManager(false);
|
||||
|
||||
readProjects(files, profiles);
|
||||
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myProjectsManager.waitForResolvingCompletion();
|
||||
myProjectsManager.scheduleImportInTests(files);
|
||||
myProjectsManager.importProjects();
|
||||
}
|
||||
});
|
||||
|
||||
for (MavenProject each : myProjectsTree.getProjects()) {
|
||||
if (each.hasReadingProblems()) {
|
||||
System.out.println(each + " has problems: " + each.getProblems());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void readProjects(List<VirtualFile> files, String... profiles) {
|
||||
myProjectsManager.resetManagedFilesAndProfilesInTests(files, new MavenExplicitProfiles(Arrays.asList(profiles)));
|
||||
waitForReadingCompletion();
|
||||
}
|
||||
|
||||
protected void updateProjectsAndImport(VirtualFile... files) {
|
||||
readProjects(files);
|
||||
myProjectsManager.performScheduledImportInTests();
|
||||
}
|
||||
|
||||
protected void initProjectsManager(boolean enableEventHandling) {
|
||||
myProjectsManager.initForTests();
|
||||
myProjectsTree = myProjectsManager.getProjectsTreeForTests();
|
||||
if (enableEventHandling) myProjectsManager.listenForExternalChanges();
|
||||
}
|
||||
|
||||
protected void scheduleResolveAll() {
|
||||
myProjectsManager.scheduleResolveAllInTests();
|
||||
}
|
||||
|
||||
protected void waitForReadingCompletion() {
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myProjectsManager.waitForReadingCompletion();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void readProjects() {
|
||||
readProjects(myProjectsManager.getProjectsFiles());
|
||||
}
|
||||
|
||||
protected void readProjects(VirtualFile... files) {
|
||||
List<MavenProject> projects = new ArrayList<MavenProject>();
|
||||
for (VirtualFile each : files) {
|
||||
projects.add(myProjectsManager.findProject(each));
|
||||
}
|
||||
myProjectsManager.forceUpdateProjects(projects);
|
||||
waitForReadingCompletion();
|
||||
}
|
||||
|
||||
protected void resolveDependenciesAndImport() {
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myProjectsManager.waitForResolvingCompletion();
|
||||
myProjectsManager.performScheduledImportInTests();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void resolveFoldersAndImport() {
|
||||
myProjectsManager.scheduleFoldersResolveForAllProjects();
|
||||
myProjectsManager.waitForFoldersResolvingCompletion();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myProjectsManager.performScheduledImportInTests();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void resolvePlugins() {
|
||||
myProjectsManager.waitForPluginsResolvingCompletion();
|
||||
}
|
||||
|
||||
protected void downloadArtifacts() {
|
||||
downloadArtifacts(myProjectsManager.getProjects(), null);
|
||||
}
|
||||
|
||||
protected MavenArtifactDownloader.DownloadResult downloadArtifacts(
|
||||
Collection<MavenProject> projects,
|
||||
List<MavenArtifact> artifacts
|
||||
) {
|
||||
final MavenArtifactDownloader.DownloadResult[] unresolved = new MavenArtifactDownloader.DownloadResult[1];
|
||||
|
||||
AsyncResult<MavenArtifactDownloader.DownloadResult> result = new AsyncResult<MavenArtifactDownloader.DownloadResult>();
|
||||
result.doWhenDone(new Consumer<MavenArtifactDownloader.DownloadResult>() {
|
||||
@Override
|
||||
public void consume(MavenArtifactDownloader.DownloadResult unresolvedArtifacts) {
|
||||
unresolved[0] = unresolvedArtifacts;
|
||||
}
|
||||
});
|
||||
|
||||
myProjectsManager.scheduleArtifactsDownloading(projects, artifacts, true, true, result);
|
||||
myProjectsManager.waitForArtifactsDownloadingCompletion();
|
||||
|
||||
return unresolved[0];
|
||||
}
|
||||
|
||||
protected void performPostImportTasks() {
|
||||
myProjectsManager.waitForPostImportTasksCompletion();
|
||||
}
|
||||
|
||||
protected void executeGoal(String relativePath, String goal) {
|
||||
VirtualFile dir = myProjectRoot.findFileByRelativePath(relativePath);
|
||||
|
||||
MavenRunnerParameters rp = new MavenRunnerParameters(true, dir.getPath(), Arrays.asList(goal), Collections.<String>emptyList());
|
||||
MavenRunnerSettings rs = new MavenRunnerSettings();
|
||||
MavenExecutor e = new MavenExternalExecutor(myProject, rp, getMavenGeneralSettings(), rs, new SoutMavenConsole());
|
||||
|
||||
e.execute(new EmptyProgressIndicator());
|
||||
}
|
||||
|
||||
protected void removeFromLocalRepository(String relativePath) throws IOException {
|
||||
FileUtil.delete(new File(getRepositoryPath(), relativePath));
|
||||
}
|
||||
|
||||
protected void setupJdkForModules(String... moduleNames) {
|
||||
for (String each : moduleNames) {
|
||||
setupJdkForModule(each);
|
||||
}
|
||||
}
|
||||
|
||||
protected Sdk setupJdkForModule(final String moduleName) {
|
||||
final Sdk sdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
|
||||
ModuleRootModificationUtil.setModuleSdk(getModule(moduleName), sdk);
|
||||
return sdk;
|
||||
}
|
||||
|
||||
protected static Sdk createJdk(String versionName) {
|
||||
return IdeaTestUtil.getMockJdk17(versionName);
|
||||
}
|
||||
|
||||
protected static AtomicInteger configConfirmationForYesAnswer() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
Messages.setTestDialog(new TestDialog() {
|
||||
@Override
|
||||
public int show(String message) {
|
||||
counter.set(counter.get() + 1);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
return counter;
|
||||
}
|
||||
|
||||
protected static AtomicInteger configConfirmationForNoAnswer() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
Messages.setTestDialog(new TestDialog() {
|
||||
@Override
|
||||
public int show(String message) {
|
||||
counter.set(counter.get() + 1);
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,9 @@ sourceSets {
|
||||
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
configureFormInstrumentation()
|
||||
|
||||
runtimeJar {
|
||||
|
||||
@@ -57,6 +57,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
testsJar()
|
||||
|
||||
projectTest {
|
||||
|
||||
@@ -23,4 +23,7 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
testsJar()
|
||||
@@ -1,24 +1,14 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.codeInsight.CodeInsightTestCase;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
|
||||
@@ -30,18 +20,12 @@ import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
public abstract class KotlinCodeInsightTestCase extends CodeInsightTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), KtTestUtil.getHomeDirectory());
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTest());
|
||||
protected void runTestRunnable(@NotNull ThrowableRunnable<Throwable> testRunnable) throws Throwable {
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTestRunnable(testRunnable));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.codeInsight.CodeInsightTestCase;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
|
||||
/**
|
||||
* Please use KotlinLightCodeInsightFixtureTestCase as the base class for all new tests.
|
||||
*/
|
||||
@WithMutedInDatabaseRunTest
|
||||
@Deprecated
|
||||
public abstract class KotlinCodeInsightTestCase extends CodeInsightTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTest());
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testFramework.TempFiles;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.ThrowableRunnable;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -88,9 +89,8 @@ public abstract class KotlinLightCodeInsightFixtureTestCaseBase extends LightCod
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
//noinspection Convert2MethodRef
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTest());
|
||||
protected void runTestRunnable(@NotNull ThrowableRunnable<Throwable> testRunnable) throws Throwable {
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTestRunnable(testRunnable));
|
||||
}
|
||||
|
||||
protected boolean isFirPlugin() {
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.nio.file.Path;
|
||||
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<Path> 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.toPath());
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -10,24 +10,17 @@ import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCa
|
||||
import com.intellij.util.ThrowableRunnable
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.TestMetadata
|
||||
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest
|
||||
import org.jetbrains.kotlin.test.runTest
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import java.io.File
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
|
||||
@WithMutedInDatabaseRunTest
|
||||
abstract class KotlinLightPlatformCodeInsightFixtureTestCase : LightPlatformCodeInsightFixtureTestCase() {
|
||||
override fun runTest() {
|
||||
runTest { super.runTest() }
|
||||
}
|
||||
|
||||
protected open fun isFirPlugin(): Boolean = false
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
enableKotlinOfficialCodeStyle(project)
|
||||
runPostStartupActivitiesOnce(project)
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
VfsRootAccess.allowRootAccess(testRootDisposable, KtTestUtil.getHomeDirectory())
|
||||
if (!isFirPlugin()) {
|
||||
invalidateLibraryCache(project)
|
||||
}
|
||||
@@ -35,7 +28,6 @@ abstract class KotlinLightPlatformCodeInsightFixtureTestCase : LightPlatformCode
|
||||
|
||||
override fun tearDown() = runAll(
|
||||
ThrowableRunnable { disableKotlinOfficialCodeStyle(project) },
|
||||
ThrowableRunnable { VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory()) },
|
||||
ThrowableRunnable { super.tearDown() },
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.vfs.newvfs.impl.VfsRootAccess
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
|
||||
import com.intellij.util.ThrowableRunnable
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.test.TestMetadata
|
||||
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest
|
||||
import org.jetbrains.kotlin.test.runTest
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import java.io.File
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
|
||||
@WithMutedInDatabaseRunTest
|
||||
abstract class KotlinLightPlatformCodeInsightFixtureTestCase : LightPlatformCodeInsightFixtureTestCase() {
|
||||
override fun runTest() {
|
||||
runTest { super.runTest() }
|
||||
}
|
||||
|
||||
protected open fun isFirPlugin(): Boolean = false
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
enableKotlinOfficialCodeStyle(project)
|
||||
runPostStartupActivitiesOnce(project)
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
if (!isFirPlugin()) {
|
||||
invalidateLibraryCache(project)
|
||||
}
|
||||
}
|
||||
|
||||
override fun tearDown() = runAll(
|
||||
ThrowableRunnable { disableKotlinOfficialCodeStyle(project) },
|
||||
ThrowableRunnable { VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory()) },
|
||||
ThrowableRunnable { super.tearDown() },
|
||||
)
|
||||
|
||||
protected fun testDataFile(fileName: String): File = File(testDataPath, fileName)
|
||||
|
||||
protected fun testDataFile(): File = testDataFile(fileName())
|
||||
|
||||
protected fun testPath(fileName: String = fileName()): String = testDataFile(fileName).toString()
|
||||
|
||||
protected fun testPath(): String = testPath(fileName())
|
||||
|
||||
protected open fun fileName(): String = KotlinTestUtils.getTestDataFileName(this::class.java, this.name) ?: (getTestName(false) + ".kt")
|
||||
|
||||
override fun getTestDataPath(): String = this::class.findAnnotation<TestMetadata>()?.value ?: super.getTestDataPath()
|
||||
}
|
||||
@@ -24,7 +24,7 @@ abstract class KotlinMultiFileTestCase : MultiFileTestCase() {
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
VfsRootAccess.allowRootAccess(testRootDisposable, KtTestUtil.getHomeDirectory())
|
||||
|
||||
runWriteAction {
|
||||
PluginTestCaseBase.addJdk(testRootDisposable, PluginTestCaseBase::mockJdk6)
|
||||
@@ -73,9 +73,4 @@ abstract class KotlinMultiFileTestCase : MultiFileTestCase() {
|
||||
PsiTestUtil.addSourceContentToRoots(myModule, rootDir)
|
||||
}
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
super.tearDown()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.test
|
||||
|
||||
import com.intellij.ide.highlighter.ModuleFileType
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.refactoring.MultiFileTestCase
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
|
||||
abstract class KotlinMultiFileTestCase : MultiFileTestCase() {
|
||||
protected var isMultiModule = false
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
|
||||
runWriteAction {
|
||||
PluginTestCaseBase.addJdk(testRootDisposable, PluginTestCaseBase::mockJdk6)
|
||||
ProjectRootManager.getInstance(project).projectSdk = PluginTestCaseBase.mockJdk6()
|
||||
}
|
||||
}
|
||||
|
||||
protected fun getTestDirName(lowercaseFirstLetter: Boolean): String {
|
||||
val testName = getTestName(lowercaseFirstLetter)
|
||||
val endIndex = testName.lastIndexOf('_')
|
||||
if (endIndex < 0) return testName
|
||||
return testName.substring(0, endIndex).replace('_', '/')
|
||||
}
|
||||
|
||||
protected fun doTestCommittingDocuments(action: (VirtualFile, VirtualFile?) -> Unit) {
|
||||
super.doTest(
|
||||
{ rootDir, rootAfter ->
|
||||
action(rootDir, rootAfter)
|
||||
|
||||
PsiDocumentManager.getInstance(project!!).commitAllDocuments()
|
||||
FileDocumentManager.getInstance().saveAllDocuments()
|
||||
}, getTestDirName(true)
|
||||
)
|
||||
}
|
||||
|
||||
override fun prepareProject(rootDir: VirtualFile) {
|
||||
if (isMultiModule) {
|
||||
val model = ModuleManager.getInstance(project).modifiableModel
|
||||
|
||||
VfsUtilCore.visitChildrenRecursively(
|
||||
rootDir,
|
||||
object : VirtualFileVisitor<Any>() {
|
||||
override fun visitFile(file: VirtualFile): Boolean {
|
||||
if (!file.isDirectory && file.name.endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) {
|
||||
model.loadModule(file.path)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
runWriteAction { model.commit() }
|
||||
} else {
|
||||
PsiTestUtil.addSourceContentToRoots(myModule, rootDir)
|
||||
}
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
super.tearDown()
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
projectTest(parallel = true) {
|
||||
dependsOn(":dist")
|
||||
workingDir = rootDir
|
||||
|
||||
@@ -25,4 +25,7 @@ dependencies {
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { none() }
|
||||
}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -19,4 +19,7 @@ dependencies {
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { none() }
|
||||
}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -22,4 +22,7 @@ dependencies {
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { none() }
|
||||
}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -21,3 +21,6 @@ sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { none() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -46,6 +46,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
projectTest(parallel = true) {
|
||||
dependsOn(":dist")
|
||||
workingDir = rootDir
|
||||
|
||||
@@ -23,4 +23,7 @@ dependencies {
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { none() }
|
||||
}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -65,10 +65,6 @@ fun AsmType.getClassDescriptor(
|
||||
}
|
||||
|
||||
return runReadAction {
|
||||
val classes = JavaPsiFacade.getInstance(scope.project).findClasses(jvmName.asString(), scope)
|
||||
if (classes.isEmpty()) null
|
||||
else {
|
||||
classes.first().getJavaClassDescriptor()
|
||||
}
|
||||
scope.project?.let(JavaPsiFacade::getInstance)?.findClasses(jvmName.asString(), scope)?.firstOrNull()?.getJavaClassDescriptor()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2000-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
|
||||
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.sun.jdi.ClassType
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import com.sun.jdi.Type as JdiType
|
||||
import org.jetbrains.org.objectweb.asm.Type as AsmType
|
||||
|
||||
fun JdiType.isSubtype(className: String): Boolean = isSubtype(AsmType.getObjectType(className))
|
||||
|
||||
fun JdiType.isSubtype(type: AsmType): Boolean {
|
||||
if (this.signature() == type.descriptor) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (type.sort != AsmType.OBJECT || this !is ClassType) {
|
||||
return false
|
||||
}
|
||||
|
||||
val superTypeName = type.className
|
||||
|
||||
if (allInterfaces().any { it.name() == superTypeName }) {
|
||||
return true
|
||||
}
|
||||
|
||||
var superClass = superclass()
|
||||
while (superClass != null) {
|
||||
if (superClass.name() == superTypeName) {
|
||||
return true
|
||||
}
|
||||
superClass = superClass.superclass()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun AsmType.getClassDescriptor(
|
||||
scope: GlobalSearchScope,
|
||||
mapBuiltIns: Boolean = true,
|
||||
moduleDescriptor: ModuleDescriptor = DefaultBuiltIns.Instance.builtInsModule
|
||||
): ClassDescriptor? {
|
||||
if (AsmUtil.isPrimitive(this)) return null
|
||||
|
||||
val jvmName = JvmClassName.byInternalName(internalName).fqNameForClassNameWithoutDollars
|
||||
|
||||
if (mapBuiltIns) {
|
||||
val mappedName = JavaToKotlinClassMap.mapJavaToKotlin(jvmName)
|
||||
if (mappedName != null) {
|
||||
moduleDescriptor.findClassAcrossModuleDependencies(mappedName)?.let { return it }
|
||||
}
|
||||
}
|
||||
|
||||
return runReadAction {
|
||||
val classes = JavaPsiFacade.getInstance(scope.project).findClasses(jvmName.asString(), scope)
|
||||
if (classes.isEmpty()) null
|
||||
else {
|
||||
classes.first().getJavaClassDescriptor()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs += "-Xsuppress-deprecated-jvm-target-warning"
|
||||
|
||||
@@ -14,3 +14,5 @@ sourceSets {
|
||||
"test" {}
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
@@ -52,6 +52,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
runtimeJar()
|
||||
|
||||
sourcesJar()
|
||||
|
||||
@@ -45,6 +45,9 @@ sourceSets {
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
jvmTarget = "11"
|
||||
javaHome = rootProject.extra["JDK_11"] as String
|
||||
|
||||
projectTest(parallel = true) {
|
||||
dependsOn(":dist")
|
||||
workingDir = rootDir
|
||||
|
||||
@@ -312,22 +312,17 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), KtTestUtil.getHomeDirectory())
|
||||
|
||||
PluginTestCaseBase.addJdk(myFixture.projectDisposable) { PluginTestCaseBase.fullJdk() }
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
// myFixture?.file?.virtualFile?.let {
|
||||
// runWriteAction {
|
||||
// if (it.isValid) {
|
||||
// it.delete(this)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
super.tearDown()
|
||||
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
ScratchFileService.getInstance().scratchesMapping.mappings.forEach { file, _ ->
|
||||
runWriteAction { file.delete(this) }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* 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.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() {
|
||||
// myFixture?.file?.virtualFile?.let {
|
||||
// runWriteAction {
|
||||
// if (it.isValid) {
|
||||
// it.delete(this)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
super.tearDown()
|
||||
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import java.util.function.Consumer
|
||||
// FIX ME WHEN BUNCH 201 REMOVED
|
||||
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase() {
|
||||
|
||||
override fun collectDocComments(file: PsiFile, sink: Consumer<PsiDocCommentBase>) {
|
||||
override fun collectDocComments(file: PsiFile, sink: Consumer<in PsiDocCommentBase>) {
|
||||
if (file !is KtFile) return
|
||||
|
||||
PsiTreeUtil.processElements(file) {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.intellij.codeInsight.javadoc.JavaDocExternalFilter
|
||||
import com.intellij.psi.PsiDocCommentBase
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.util.function.Consumer
|
||||
|
||||
// FIX ME WHEN BUNCH 201 REMOVED
|
||||
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase() {
|
||||
|
||||
override fun collectDocComments(file: PsiFile, sink: Consumer<PsiDocCommentBase>) {
|
||||
if (file !is KtFile) return
|
||||
|
||||
PsiTreeUtil.processElements(file) {
|
||||
val comment = (it as? KtDeclaration)?.docComment
|
||||
if (comment != null) sink.accept(comment)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun generateRenderedDoc(element: PsiElement): String? {
|
||||
val docComment = (element as? KtDeclaration)?.docComment ?: return null
|
||||
|
||||
val result = StringBuilder().also {
|
||||
it.renderKDoc(docComment.getDefaultSection(), docComment.getAllSections())
|
||||
}
|
||||
|
||||
return JavaDocExternalFilter.filterInternalDocInfo(result.toString())
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ class NewKotlinFileAction : CreateFileFromTemplateAction(
|
||||
override fun postProcess(createdElement: PsiFile, templateName: String?, customProperties: Map<String, String>?) {
|
||||
super.postProcess(createdElement, templateName, customProperties)
|
||||
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(createdElement)
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(createdElement!!)
|
||||
|
||||
if (createdElement is KtFile) {
|
||||
if (module != null) {
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* 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)
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2000-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.framework
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.projectRoots.*
|
||||
import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl
|
||||
import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil
|
||||
import com.intellij.util.Consumer
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import javax.swing.JComponent
|
||||
|
||||
class KotlinSdkType : SdkType("KotlinSDK") {
|
||||
companion object {
|
||||
@JvmField
|
||||
val INSTANCE = KotlinSdkType()
|
||||
|
||||
val defaultHomePath: String
|
||||
get() = PathUtil.kotlinPathsForIdeaPlugin.homePath.absolutePath
|
||||
|
||||
@JvmOverloads
|
||||
fun setUpIfNeeded(disposable: Disposable? = null, checkIfNeeded: () -> Boolean = { true }) {
|
||||
val projectSdks: Array<Sdk> = ProjectJdkTable.getInstance().allJdks
|
||||
if (projectSdks.any { it.sdkType is KotlinSdkType }) return
|
||||
if (!checkIfNeeded()) return // do not create Kotlin SDK
|
||||
|
||||
val newSdkName = SdkConfigurationUtil.createUniqueSdkName(INSTANCE, defaultHomePath, projectSdks.toList())
|
||||
val newJdk = ProjectJdkImpl(newSdkName, INSTANCE)
|
||||
newJdk.homePath = defaultHomePath
|
||||
INSTANCE.setupSdkPaths(newJdk)
|
||||
|
||||
ApplicationManager.getApplication().invokeAndWait {
|
||||
runWriteAction {
|
||||
if (ProjectJdkTable.getInstance().allJdks.any { it.sdkType is KotlinSdkType }) return@runWriteAction
|
||||
if (disposable != null) {
|
||||
ProjectJdkTable.getInstance().addJdk(newJdk, disposable)
|
||||
} else {
|
||||
ProjectJdkTable.getInstance().addJdk(newJdk)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPresentableName() = KotlinBundle.message("framework.name.kotlin.sdk")
|
||||
|
||||
override fun getIcon() = KotlinIcons.SMALL_LOGO
|
||||
|
||||
override fun isValidSdkHome(path: String?) = true
|
||||
|
||||
override fun suggestSdkName(currentSdkName: String?, sdkHome: String?) = "Kotlin SDK"
|
||||
|
||||
override fun suggestHomePath() = null
|
||||
|
||||
override fun sdkHasValidPath(sdk: Sdk) = true
|
||||
|
||||
override fun getVersionString(sdk: Sdk) = bundledRuntimeVersion()
|
||||
|
||||
override fun supportsCustomCreateUI() = true
|
||||
|
||||
override fun showCustomCreateUI(sdkModel: SdkModel, parentComponent: JComponent, selectedSdk: Sdk?, sdkCreatedCallback: Consumer<in Sdk>) {
|
||||
sdkCreatedCallback.consume(createSdkWithUniqueName(sdkModel.sdks.toList()))
|
||||
}
|
||||
|
||||
fun createSdkWithUniqueName(existingSdks: Collection<Sdk>): ProjectJdkImpl {
|
||||
val sdkName = suggestSdkName(SdkConfigurationUtil.createUniqueSdkName(this, "", existingSdks), "")
|
||||
return ProjectJdkImpl(sdkName, this).apply {
|
||||
homePath = defaultHomePath
|
||||
}
|
||||
}
|
||||
|
||||
override fun createAdditionalDataConfigurable(sdkModel: SdkModel, sdkModificator: SdkModificator) = null
|
||||
|
||||
override fun saveAdditionalData(additionalData: SdkAdditionalData, additional: Element) {
|
||||
|
||||
}
|
||||
|
||||
override fun allowCreationByUser(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,9 @@
|
||||
package org.jetbrains.kotlin.idea.highlighter.markers
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.GutterIconTooltipHelper
|
||||
import com.intellij.codeInsight.daemon.impl.MarkerType
|
||||
import com.intellij.ide.util.DefaultPsiElementCellRenderer
|
||||
import com.intellij.ide.util.PsiClassListCellRenderer
|
||||
import com.intellij.java.analysis.JavaAnalysisBundle
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.psi.NavigatablePsiElement
|
||||
@@ -97,7 +97,7 @@ fun buildNavigateToPropertyOverriddenDeclarationsPopup(e: MouseEvent?, element:
|
||||
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||
/* runnable */ ktPsiMethodProcessor,
|
||||
MarkerType.SEARCHING_FOR_OVERRIDING_METHODS,
|
||||
JavaAnalysisBundle.message("searching.for.overriding.methods"),
|
||||
/* can be canceled */ true,
|
||||
project,
|
||||
e?.component as JComponent?
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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.markers
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.GutterIconTooltipHelper
|
||||
import com.intellij.codeInsight.daemon.impl.MarkerType
|
||||
import com.intellij.ide.util.DefaultPsiElementCellRenderer
|
||||
import com.intellij.ide.util.PsiClassListCellRenderer
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.psi.NavigatablePsiElement
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.PsiElementProcessor
|
||||
import com.intellij.psi.search.PsiElementProcessorAdapter
|
||||
import com.intellij.util.AdapterProcessor
|
||||
import com.intellij.util.CommonProcessors
|
||||
import com.intellij.util.Function
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingMethod
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDefinitionsSearcher
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import java.awt.event.MouseEvent
|
||||
import javax.swing.JComponent
|
||||
|
||||
fun getOverriddenPropertyTooltip(property: KtNamedDeclaration): String? {
|
||||
val overriddenInClassesProcessor = PsiElementProcessor.CollectElementsWithLimit<PsiClass>(5)
|
||||
|
||||
val consumer = AdapterProcessor<PsiMethod, PsiClass>(
|
||||
CommonProcessors.UniqueProcessor<PsiClass>(PsiElementProcessorAdapter(overriddenInClassesProcessor)),
|
||||
Function { method: PsiMethod? -> method?.containingClass }
|
||||
)
|
||||
|
||||
for (method in property.toPossiblyFakeLightMethods()) {
|
||||
if (!overriddenInClassesProcessor.isOverflow) {
|
||||
method.forEachOverridingMethod(processor = consumer::process)
|
||||
}
|
||||
}
|
||||
|
||||
val isImplemented = isImplemented(property)
|
||||
if (overriddenInClassesProcessor.isOverflow) {
|
||||
return if (isImplemented)
|
||||
KotlinBundle.message("overridden.marker.implementations.multiple")
|
||||
else
|
||||
KotlinBundle.message("overridden.marker.overrides.multiple")
|
||||
}
|
||||
|
||||
val collectedClasses = overriddenInClassesProcessor.collection
|
||||
if (collectedClasses.isEmpty()) return null
|
||||
|
||||
val start = if (isImplemented)
|
||||
KotlinBundle.message("overridden.marker.implementation")
|
||||
else
|
||||
KotlinBundle.message("overridden.marker.overrides")
|
||||
|
||||
val pattern = " {0}"
|
||||
return GutterIconTooltipHelper.composeText(collectedClasses.sortedWith(PsiClassListCellRenderer().comparator), start, pattern)
|
||||
}
|
||||
|
||||
fun buildNavigateToPropertyOverriddenDeclarationsPopup(e: MouseEvent?, element: PsiElement?): NavigationPopupDescriptor? {
|
||||
val propertyOrParameter = element?.parent as? KtNamedDeclaration ?: return null
|
||||
val project = propertyOrParameter.project
|
||||
|
||||
if (DumbService.isDumb(project)) {
|
||||
DumbService.getInstance(project)?.showDumbModeNotification(
|
||||
KotlinBundle.message("highlighter.notification.text.navigation.to.overriding.classes.is.not.possible.during.index.update"))
|
||||
return null
|
||||
}
|
||||
|
||||
val psiPropertyMethods = propertyOrParameter.toPossiblyFakeLightMethods()
|
||||
val elementProcessor = CommonProcessors.CollectUniquesProcessor<PsiElement>()
|
||||
val ktPsiMethodProcessor = Runnable {
|
||||
KotlinDefinitionsSearcher.processPropertyImplementationsMethods(
|
||||
psiPropertyMethods,
|
||||
GlobalSearchScope.allScope(project),
|
||||
elementProcessor
|
||||
)
|
||||
}
|
||||
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||
/* runnable */ ktPsiMethodProcessor,
|
||||
MarkerType.SEARCHING_FOR_OVERRIDING_METHODS,
|
||||
/* can be canceled */ true,
|
||||
project,
|
||||
e?.component as JComponent?
|
||||
)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
val renderer = DefaultPsiElementCellRenderer()
|
||||
val navigatingOverrides = elementProcessor.results
|
||||
.sortedWith(renderer.comparator)
|
||||
.filterIsInstance<NavigatablePsiElement>()
|
||||
|
||||
return NavigationPopupDescriptor(
|
||||
navigatingOverrides,
|
||||
KotlinBundle.message("overridden.marker.implementations.choose.implementation.title", propertyOrParameter.name.toString()),
|
||||
KotlinBundle.message("overridden.marker.implementations.choose.implementation.find.usages", propertyOrParameter.name.toString()), renderer
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun isImplemented(declaration: KtNamedDeclaration): Boolean {
|
||||
if (declaration.hasModifier(KtTokens.ABSTRACT_KEYWORD)) return true
|
||||
|
||||
var parent = declaration.parent
|
||||
parent = if (parent is KtClassBody) parent.getParent() else parent
|
||||
|
||||
if (parent !is KtClass) return false
|
||||
|
||||
return parent.isInterface() && (declaration !is KtDeclarationWithBody || !declaration.hasBody()) && (declaration !is KtDeclarationWithInitializer || !declaration.hasInitializer())
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ abstract class ITNReporterCompat : ITNReporter() {
|
||||
events: Array<IdeaLoggingEvent>,
|
||||
additionalInfo: String?,
|
||||
parentComponent: Component,
|
||||
consumer: Consumer<SubmittedReportInfo>
|
||||
consumer: Consumer<in SubmittedReportInfo>
|
||||
): Boolean {
|
||||
return submitCompat(events, additionalInfo, parentComponent, consumer)
|
||||
}
|
||||
@@ -25,7 +25,7 @@ abstract class ITNReporterCompat : ITNReporter() {
|
||||
events: Array<IdeaLoggingEvent>,
|
||||
additionalInfo: String?,
|
||||
parentComponent: Component?,
|
||||
consumer: Consumer<SubmittedReportInfo>
|
||||
consumer: Consumer<in SubmittedReportInfo>
|
||||
): Boolean {
|
||||
@Suppress("IncompatibleAPI")
|
||||
return super.submit(events, additionalInfo, parentComponent ?: error("Should never happen in Intellij Idea"), consumer)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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 ?: error("Should never happen in Intellij Idea"), consumer)
|
||||
}
|
||||
}
|
||||
@@ -226,7 +226,7 @@ class KotlinReportSubmitter : ITNReporterCompat() {
|
||||
events: Array<IdeaLoggingEvent>,
|
||||
additionalInfo: String?,
|
||||
parentComponent: Component?,
|
||||
consumer: Consumer<SubmittedReportInfo>
|
||||
consumer: Consumer<in SubmittedReportInfo>
|
||||
): Boolean {
|
||||
if (hasUpdate) {
|
||||
if (ApplicationManager.getApplication().isInternal) {
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* 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.reporter
|
||||
|
||||
import com.intellij.diagnostic.ReportMessages
|
||||
import com.intellij.ide.DataManager
|
||||
import com.intellij.ide.util.PropertiesComponent
|
||||
import com.intellij.notification.NotificationType
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.diagnostic.IdeaLoggingEvent
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.diagnostic.SubmittedReportInfo
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.util.Consumer
|
||||
import com.intellij.util.ThreeState
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.KotlinPluginUpdater
|
||||
import org.jetbrains.kotlin.idea.KotlinPluginUtil
|
||||
import org.jetbrains.kotlin.idea.PluginUpdateStatus
|
||||
import org.jetbrains.kotlin.idea.util.isEap
|
||||
import java.awt.Component
|
||||
import java.io.IOException
|
||||
import java.time.LocalDate
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.DateTimeParseException
|
||||
import java.time.temporal.ChronoUnit
|
||||
import javax.swing.Icon
|
||||
|
||||
/**
|
||||
* We need to wrap ITNReporter for force showing or errors from kotlin plugin even from released version of IDEA.
|
||||
*/
|
||||
class KotlinReportSubmitter : ITNReporterCompat() {
|
||||
companion object {
|
||||
private const val KOTLIN_FATAL_ERROR_NOTIFICATION_PROPERTY = "kotlin.fatal.error.notification"
|
||||
private const val IDEA_FATAL_ERROR_NOTIFICATION_PROPERTY = "idea.fatal.error.notification"
|
||||
private const val DISABLED_VALUE = "disabled"
|
||||
private const val ENABLED_VALUE = "enabled"
|
||||
|
||||
private const val KOTLIN_PLUGIN_RELEASE_DATE = "kotlin.plugin.releaseDate"
|
||||
|
||||
private val LOG = Logger.getInstance(KotlinReportSubmitter::class.java)
|
||||
|
||||
@Volatile
|
||||
private var isFatalErrorReportingDisabledInRelease = ThreeState.UNSURE
|
||||
|
||||
private val isIdeaAndKotlinRelease by lazy {
|
||||
// Disabled in released version of IDEA and Android Studio
|
||||
// Enabled in EAPs, Canary and Beta
|
||||
val isReleaseLikeIdea = DISABLED_VALUE == System.getProperty(IDEA_FATAL_ERROR_NOTIFICATION_PROPERTY, ENABLED_VALUE)
|
||||
|
||||
val isKotlinRelease =
|
||||
!(KotlinPluginUtil.isSnapshotVersion() || KotlinPluginUtil.isDevVersion() || isEap(KotlinPluginUtil.getPluginVersion()))
|
||||
|
||||
isReleaseLikeIdea && isKotlinRelease
|
||||
}
|
||||
|
||||
private const val NUMBER_OF_REPORTING_DAYS_FROM_RELEASE = 7
|
||||
|
||||
fun setupReportingFromRelease() {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!isIdeaAndKotlinRelease) {
|
||||
return
|
||||
}
|
||||
|
||||
val currentPluginReleaseDate = readStoredPluginReleaseDate()
|
||||
if (currentPluginReleaseDate != null) {
|
||||
isFatalErrorReportingDisabledInRelease =
|
||||
if (isFatalErrorReportingDisabled(currentPluginReleaseDate)) ThreeState.YES else ThreeState.NO
|
||||
return
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().executeOnPooledThread {
|
||||
val releaseDate =
|
||||
try {
|
||||
KotlinPluginUpdater.fetchPluginReleaseDate(
|
||||
KotlinPluginUtil.KOTLIN_PLUGIN_ID,
|
||||
KotlinPluginUtil.getPluginVersion(),
|
||||
null
|
||||
)
|
||||
} catch (e: IOException) {
|
||||
LOG.warn(e)
|
||||
null
|
||||
} catch (e: KotlinPluginUpdater.Companion.ResponseParseException) {
|
||||
// Exception won't be shown, but will be logged
|
||||
LOG.error(e)
|
||||
return@executeOnPooledThread
|
||||
}
|
||||
|
||||
if (releaseDate != null) {
|
||||
writePluginReleaseValue(releaseDate)
|
||||
} else {
|
||||
// Will try to fetch the same release date on IDE restart
|
||||
}
|
||||
|
||||
isFatalErrorReportingDisabledInRelease = isFatalErrorReportingWithDefault(releaseDate)
|
||||
}
|
||||
}
|
||||
|
||||
private fun isFatalErrorReportingWithDefault(releaseDate: LocalDate?): ThreeState {
|
||||
return if (releaseDate != null) {
|
||||
if (isFatalErrorReportingDisabled(releaseDate)) ThreeState.YES else ThreeState.NO
|
||||
} else {
|
||||
// Disable reporting by default until we obtain a valid release date.
|
||||
// We might fail reporting exceptions that happened before initialization but after successful release date fetching
|
||||
// such exceptions maybe be reported after restart.
|
||||
ThreeState.YES
|
||||
}
|
||||
}
|
||||
|
||||
private fun isFatalErrorReportingDisabledWithUpdate(): Boolean {
|
||||
val currentPluginReleaseDate = readStoredPluginReleaseDate()
|
||||
isFatalErrorReportingDisabledInRelease = isFatalErrorReportingWithDefault(currentPluginReleaseDate)
|
||||
|
||||
return isFatalErrorReportingDisabledInRelease == ThreeState.YES
|
||||
}
|
||||
|
||||
private fun isFatalErrorReportingDisabled(releaseDate: LocalDate): Boolean {
|
||||
return ChronoUnit.DAYS.between(releaseDate, LocalDate.now()) > NUMBER_OF_REPORTING_DAYS_FROM_RELEASE
|
||||
}
|
||||
|
||||
private val RELEASE_DATE_FORMATTER: DateTimeFormatter by lazy {
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd")
|
||||
}
|
||||
|
||||
private fun readStoredPluginReleaseDate(): LocalDate? {
|
||||
val pluginVersionToReleaseDate = PropertiesComponent.getInstance().getValue(KOTLIN_PLUGIN_RELEASE_DATE) ?: return null
|
||||
|
||||
val parsedDate = fun(): LocalDate? {
|
||||
val parts = pluginVersionToReleaseDate.split(":")
|
||||
if (parts.size != 2) {
|
||||
return null
|
||||
}
|
||||
|
||||
val pluginVersion = parts[0]
|
||||
if (pluginVersion != KotlinPluginUtil.getPluginVersion()) {
|
||||
// Stored for some other plugin version
|
||||
return null
|
||||
}
|
||||
|
||||
return try {
|
||||
val dateString = parts[1]
|
||||
LocalDate.parse(dateString, RELEASE_DATE_FORMATTER)
|
||||
} catch (e: DateTimeParseException) {
|
||||
null
|
||||
}
|
||||
}.invoke()
|
||||
|
||||
if (parsedDate == null) {
|
||||
PropertiesComponent.getInstance().setValue(KOTLIN_PLUGIN_RELEASE_DATE, null)
|
||||
}
|
||||
|
||||
return parsedDate
|
||||
}
|
||||
|
||||
private fun writePluginReleaseValue(date: LocalDate) {
|
||||
val currentKotlinVersion = KotlinPluginUtil.getPluginVersion()
|
||||
val dateStr = RELEASE_DATE_FORMATTER.format(date)
|
||||
PropertiesComponent.getInstance().setValue(KOTLIN_PLUGIN_RELEASE_DATE, "$currentKotlinVersion:$dateStr")
|
||||
}
|
||||
}
|
||||
|
||||
private var hasUpdate = false
|
||||
private var hasLatestVersion = false
|
||||
|
||||
override fun showErrorInRelease(event: IdeaLoggingEvent): Boolean {
|
||||
if (ApplicationManager.getApplication().isInternal) {
|
||||
// Reporting is always enabled for internal mode in the platform
|
||||
return true
|
||||
}
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (hasUpdate) {
|
||||
return false
|
||||
}
|
||||
|
||||
val kotlinNotificationEnabled = DISABLED_VALUE != System.getProperty(KOTLIN_FATAL_ERROR_NOTIFICATION_PROPERTY, ENABLED_VALUE)
|
||||
if (!kotlinNotificationEnabled) {
|
||||
// Kotlin notifications are explicitly disabled
|
||||
return false
|
||||
}
|
||||
|
||||
if (!isIdeaAndKotlinRelease) {
|
||||
return true
|
||||
}
|
||||
|
||||
return when (isFatalErrorReportingDisabledInRelease) {
|
||||
ThreeState.YES ->
|
||||
false
|
||||
|
||||
ThreeState.NO -> {
|
||||
// Reiterate the check for the case when there was no restart for long and reporting decision might expire
|
||||
!isFatalErrorReportingDisabledWithUpdate()
|
||||
}
|
||||
|
||||
ThreeState.UNSURE -> {
|
||||
// There might be an exception while initialization isn't complete.
|
||||
// Decide urgently based on previously stored release version if already fetched.
|
||||
!isFatalErrorReportingDisabledWithUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun submitCompat(
|
||||
events: Array<IdeaLoggingEvent>,
|
||||
additionalInfo: String?,
|
||||
parentComponent: Component?,
|
||||
consumer: Consumer<SubmittedReportInfo>
|
||||
): Boolean {
|
||||
if (hasUpdate) {
|
||||
if (ApplicationManager.getApplication().isInternal) {
|
||||
return super.submitCompat(events, additionalInfo, parentComponent, consumer)
|
||||
}
|
||||
|
||||
// TODO: What happens here? User clicks report but no report is send?
|
||||
return true
|
||||
}
|
||||
|
||||
if (hasLatestVersion) {
|
||||
return super.submitCompat(events, additionalInfo, parentComponent, consumer)
|
||||
}
|
||||
|
||||
val project: Project? = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parentComponent))
|
||||
if (KotlinPluginUtil.isPatched()) {
|
||||
ReportMessages.GROUP
|
||||
.createNotification(
|
||||
ReportMessages.ERROR_REPORT,
|
||||
KotlinBundle.message("reporter.text.can.t.report.exception.from.patched.plugin"),
|
||||
NotificationType.INFORMATION,
|
||||
null
|
||||
)
|
||||
.setImportant(false)
|
||||
.notify(project)
|
||||
return true
|
||||
}
|
||||
|
||||
KotlinPluginUpdater.getInstance().runUpdateCheck { status ->
|
||||
if (status is PluginUpdateStatus.Update) {
|
||||
hasUpdate = true
|
||||
|
||||
if (ApplicationManager.getApplication().isInternal) {
|
||||
super.submitCompat(events, additionalInfo, parentComponent, consumer)
|
||||
}
|
||||
|
||||
val rc = showDialog(
|
||||
parentComponent,
|
||||
KotlinBundle.message(
|
||||
"reporter.message.text.you.re.running.kotlin.plugin.version",
|
||||
KotlinPluginUtil.getPluginVersion(),
|
||||
status.pluginDescriptor.version
|
||||
),
|
||||
KotlinBundle.message("reporter.title.update.kotlin.plugin"),
|
||||
arrayOf(KotlinBundle.message("reporter.button.text.update"), KotlinBundle.message("reporter.button.text.ignore")),
|
||||
0, Messages.getInformationIcon()
|
||||
)
|
||||
|
||||
if (rc == 0) {
|
||||
KotlinPluginUpdater.getInstance().installPluginUpdate(status)
|
||||
}
|
||||
} else {
|
||||
hasLatestVersion = true
|
||||
super.submitCompat(events, additionalInfo, parentComponent, consumer)
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun showDialog(parent: Component?, message: String, title: String, options: Array<String>, defaultOptionIndex: Int, icon: Icon?): Int {
|
||||
return if (parent != null) {
|
||||
Messages.showDialog(parent, message, title, options, defaultOptionIndex, icon)
|
||||
} else {
|
||||
Messages.showDialog(message, title, options, defaultOptionIndex, icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,13 +12,7 @@ import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
abstract public class KotlinDaemonAnalyzerTestCase extends DaemonAnalyzerTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), KtTestUtil.getHomeDirectory());
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
|
||||
abstract public class KotlinDaemonAnalyzerTestCase extends DaemonAnalyzerTestCase {
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory());
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,10 @@ import org.jetbrains.kotlin.idea.caches.project.ModuleTestSourceInfo
|
||||
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.platform
|
||||
import org.jetbrains.kotlin.idea.stubs.createMultiplatformFacetM3
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase.*
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import org.jetbrains.kotlin.test.util.addDependency
|
||||
@@ -318,7 +316,6 @@ class IdeaModuleInfoTest : ModuleTestCase() {
|
||||
a.addDependency(stdlibJvm)
|
||||
|
||||
val b = module("b")
|
||||
b.setUpPlatform(JsPlatforms.defaultJsPlatform)
|
||||
b.addDependency(stdlibCommon)
|
||||
b.addDependency(stdlibJs)
|
||||
|
||||
@@ -483,23 +480,9 @@ class IdeaModuleInfoTest : ModuleTestCase() {
|
||||
kind = JSLibraryKind
|
||||
)
|
||||
|
||||
private fun Module.setUpPlatform(targetPlatform: TargetPlatform) {
|
||||
createMultiplatformFacetM3(
|
||||
platformKind = targetPlatform,
|
||||
dependsOnModuleNames = listOf(),
|
||||
pureKotlinSourceFolders = listOf(),
|
||||
)
|
||||
}
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
|
||||
super.tearDown()
|
||||
VfsRootAccess.allowRootAccess(testRootDisposable, KtTestUtil.getHomeDirectory())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,505 @@
|
||||
/*
|
||||
* 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.caches.resolve
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.module.StdModuleTypes
|
||||
import com.intellij.openapi.roots.DependencyScope
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.testFramework.ModuleTestCase
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.idea.caches.project.*
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleTestSourceInfo
|
||||
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.platform
|
||||
import org.jetbrains.kotlin.idea.stubs.createMultiplatformFacetM3
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase.*
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.idea.util.getProjectJdkTableSafe
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import org.jetbrains.kotlin.test.util.addDependency
|
||||
import org.jetbrains.kotlin.test.util.jarRoot
|
||||
import org.jetbrains.kotlin.test.util.projectLibrary
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import org.junit.Assert
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||
class IdeaModuleInfoTest : ModuleTestCase() {
|
||||
fun testSimpleModuleDependency() {
|
||||
val (a, b) = modules()
|
||||
b.addDependency(a)
|
||||
|
||||
b.production.assertDependenciesEqual(b.production, a.production)
|
||||
UsefulTestCase.assertDoesntContain(a.production.dependencies(), b.production)
|
||||
}
|
||||
|
||||
fun testCircularDependency() {
|
||||
val (a, b) = modules()
|
||||
|
||||
b.addDependency(a)
|
||||
a.addDependency(b)
|
||||
|
||||
a.production.assertDependenciesEqual(a.production, b.production)
|
||||
b.production.assertDependenciesEqual(b.production, a.production)
|
||||
}
|
||||
|
||||
fun testExportedDependency() {
|
||||
val (a, b, c) = modules()
|
||||
|
||||
b.addDependency(a, exported = true)
|
||||
c.addDependency(b)
|
||||
|
||||
a.production.assertDependenciesEqual(a.production)
|
||||
b.production.assertDependenciesEqual(b.production, a.production)
|
||||
c.production.assertDependenciesEqual(c.production, b.production, a.production)
|
||||
}
|
||||
|
||||
fun testRedundantExportedDependency() {
|
||||
val (a, b, c) = modules()
|
||||
|
||||
b.addDependency(a, exported = true)
|
||||
c.addDependency(a)
|
||||
c.addDependency(b)
|
||||
|
||||
a.production.assertDependenciesEqual(a.production)
|
||||
b.production.assertDependenciesEqual(b.production, a.production)
|
||||
c.production.assertDependenciesEqual(c.production, a.production, b.production)
|
||||
}
|
||||
|
||||
fun testCircularExportedDependency() {
|
||||
val (a, b, c) = modules()
|
||||
|
||||
b.addDependency(a, exported = true)
|
||||
c.addDependency(b, exported = true)
|
||||
a.addDependency(c, exported = true)
|
||||
|
||||
a.production.assertDependenciesEqual(a.production, c.production, b.production)
|
||||
b.production.assertDependenciesEqual(b.production, a.production, c.production)
|
||||
c.production.assertDependenciesEqual(c.production, b.production, a.production)
|
||||
}
|
||||
|
||||
fun testSimpleLibDependency() {
|
||||
val a = module("a")
|
||||
val lib = projectLibrary()
|
||||
a.addDependency(lib)
|
||||
|
||||
a.production.assertDependenciesEqual(a.production, lib.classes)
|
||||
}
|
||||
|
||||
fun testCircularExportedDependencyWithLib() {
|
||||
val (a, b, c) = modules()
|
||||
|
||||
val lib = projectLibrary()
|
||||
|
||||
a.addDependency(lib)
|
||||
|
||||
b.addDependency(a, exported = true)
|
||||
c.addDependency(b, exported = true)
|
||||
a.addDependency(c, exported = true)
|
||||
|
||||
b.addDependency(lib)
|
||||
c.addDependency(lib)
|
||||
|
||||
a.production.assertDependenciesEqual(a.production, lib.classes, c.production, b.production)
|
||||
b.production.assertDependenciesEqual(b.production, a.production, c.production, lib.classes)
|
||||
c.production.assertDependenciesEqual(c.production, b.production, a.production, lib.classes)
|
||||
}
|
||||
|
||||
fun testSeveralModulesExportLibs() {
|
||||
val (a, b, c) = modules()
|
||||
|
||||
val lib1 = projectLibrary("lib1")
|
||||
val lib2 = projectLibrary("lib2")
|
||||
|
||||
a.addDependency(lib1, exported = true)
|
||||
b.addDependency(lib2, exported = true)
|
||||
c.addDependency(a)
|
||||
c.addDependency(b)
|
||||
|
||||
c.production.assertDependenciesEqual(c.production, a.production, lib1.classes, b.production, lib2.classes)
|
||||
}
|
||||
|
||||
fun testSeveralModulesExportSameLib() {
|
||||
val (a, b, c) = modules()
|
||||
|
||||
val lib = projectLibrary()
|
||||
|
||||
a.addDependency(lib, exported = true)
|
||||
b.addDependency(lib, exported = true)
|
||||
c.addDependency(a)
|
||||
c.addDependency(b)
|
||||
|
||||
c.production.assertDependenciesEqual(c.production, a.production, lib.classes, b.production)
|
||||
}
|
||||
|
||||
fun testRuntimeDependency() {
|
||||
val (a, b) = modules()
|
||||
|
||||
b.addDependency(a, dependencyScope = DependencyScope.RUNTIME)
|
||||
b.addDependency(projectLibrary(), dependencyScope = DependencyScope.RUNTIME)
|
||||
|
||||
b.production.assertDependenciesEqual(b.production)
|
||||
}
|
||||
|
||||
fun testProvidedDependency() {
|
||||
val (a, b) = modules()
|
||||
val lib = projectLibrary()
|
||||
|
||||
b.addDependency(a, dependencyScope = DependencyScope.PROVIDED)
|
||||
b.addDependency(lib, dependencyScope = DependencyScope.PROVIDED)
|
||||
|
||||
b.production.assertDependenciesEqual(b.production, a.production, lib.classes)
|
||||
}
|
||||
|
||||
fun testSimpleTestDependency() {
|
||||
val (a, b) = modules()
|
||||
b.addDependency(a, dependencyScope = DependencyScope.TEST)
|
||||
|
||||
a.production.assertDependenciesEqual(a.production)
|
||||
a.test.assertDependenciesEqual(a.test, a.production)
|
||||
b.production.assertDependenciesEqual(b.production)
|
||||
b.test.assertDependenciesEqual(b.test, b.production, a.test, a.production)
|
||||
}
|
||||
|
||||
fun testLibTestDependency() {
|
||||
val a = module("a")
|
||||
val lib = projectLibrary()
|
||||
a.addDependency(lib, dependencyScope = DependencyScope.TEST)
|
||||
|
||||
a.production.assertDependenciesEqual(a.production)
|
||||
a.test.assertDependenciesEqual(a.test, a.production, lib.classes)
|
||||
}
|
||||
|
||||
fun testExportedTestDependency() {
|
||||
val (a, b, c) = modules()
|
||||
b.addDependency(a, exported = true)
|
||||
c.addDependency(b, dependencyScope = DependencyScope.TEST)
|
||||
|
||||
c.production.assertDependenciesEqual(c.production)
|
||||
c.test.assertDependenciesEqual(c.test, c.production, b.test, b.production, a.test, a.production)
|
||||
}
|
||||
|
||||
fun testDependents() {
|
||||
//NOTE: we do not differ between dependency kinds
|
||||
val (a, b, c) = modules(name1 = "a", name2 = "b", name3 = "c")
|
||||
val (d, e, f) = modules(name1 = "d", name2 = "e", name3 = "f")
|
||||
|
||||
b.addDependency(a, exported = true)
|
||||
|
||||
c.addDependency(a)
|
||||
|
||||
d.addDependency(c, exported = true)
|
||||
|
||||
e.addDependency(b)
|
||||
|
||||
f.addDependency(d)
|
||||
f.addDependency(e)
|
||||
|
||||
|
||||
a.test.assertDependentsEqual(a.test, b.test, c.test, e.test)
|
||||
a.production.assertDependentsEqual(a.production, a.test, b.production, b.test, c.production, c.test, e.production, e.test)
|
||||
|
||||
b.test.assertDependentsEqual(b.test, e.test)
|
||||
b.production.assertDependentsEqual(b.production, b.test, e.production, e.test)
|
||||
|
||||
|
||||
c.test.assertDependentsEqual(c.test, d.test, f.test)
|
||||
c.production.assertDependentsEqual(c.production, c.test, d.production, d.test, f.production, f.test)
|
||||
|
||||
d.test.assertDependentsEqual(d.test, f.test)
|
||||
d.production.assertDependentsEqual(d.production, d.test, f.production, f.test)
|
||||
|
||||
e.test.assertDependentsEqual(e.test, f.test)
|
||||
e.production.assertDependentsEqual(e.production, e.test, f.production, f.test)
|
||||
|
||||
f.test.assertDependentsEqual(f.test)
|
||||
f.production.assertDependentsEqual(f.production, f.test)
|
||||
}
|
||||
|
||||
fun testLibraryDependency1() {
|
||||
val lib1 = projectLibrary("lib1")
|
||||
val lib2 = projectLibrary("lib2")
|
||||
|
||||
val module = module("module")
|
||||
module.addDependency(lib1)
|
||||
module.addDependency(lib2)
|
||||
|
||||
lib1.classes.assertAdditionalLibraryDependencies(lib2.classes)
|
||||
lib2.classes.assertAdditionalLibraryDependencies(lib1.classes)
|
||||
}
|
||||
|
||||
fun testLibraryDependency2() {
|
||||
val lib1 = projectLibrary("lib1")
|
||||
val lib2 = projectLibrary("lib2")
|
||||
val lib3 = projectLibrary("lib3")
|
||||
|
||||
val (a, b, c) = modules()
|
||||
a.addDependency(lib1)
|
||||
b.addDependency(lib2)
|
||||
c.addDependency(lib3)
|
||||
|
||||
c.addDependency(a)
|
||||
c.addDependency(b)
|
||||
|
||||
lib1.classes.assertAdditionalLibraryDependencies()
|
||||
lib2.classes.assertAdditionalLibraryDependencies()
|
||||
lib3.classes.assertAdditionalLibraryDependencies(lib1.classes, lib2.classes)
|
||||
}
|
||||
|
||||
fun testLibraryDependency3() {
|
||||
val lib1 = projectLibrary("lib1")
|
||||
val lib2 = projectLibrary("lib2")
|
||||
val lib3 = projectLibrary("lib3")
|
||||
|
||||
val (a, b) = modules()
|
||||
a.addDependency(lib1)
|
||||
b.addDependency(lib2)
|
||||
|
||||
a.addDependency(lib3)
|
||||
b.addDependency(lib3)
|
||||
|
||||
lib1.classes.assertAdditionalLibraryDependencies(lib3.classes)
|
||||
lib2.classes.assertAdditionalLibraryDependencies(lib3.classes)
|
||||
lib3.classes.assertAdditionalLibraryDependencies(lib1.classes, lib2.classes)
|
||||
}
|
||||
|
||||
fun testRoots() {
|
||||
val a = module("a", hasProductionRoot = true, hasTestRoot = false)
|
||||
|
||||
val empty = module("empty", hasProductionRoot = false, hasTestRoot = false)
|
||||
a.addDependency(empty)
|
||||
|
||||
val b = module("b", hasProductionRoot = false, hasTestRoot = true)
|
||||
b.addDependency(a)
|
||||
|
||||
val c = module("c")
|
||||
c.addDependency(b)
|
||||
c.addDependency(a)
|
||||
|
||||
assertNotNull(a.productionSourceInfo())
|
||||
assertNull(a.testSourceInfo())
|
||||
|
||||
assertNull(empty.productionSourceInfo())
|
||||
assertNull(empty.testSourceInfo())
|
||||
|
||||
assertNull(b.productionSourceInfo())
|
||||
assertNotNull(b.testSourceInfo())
|
||||
|
||||
b.test.assertDependenciesEqual(b.test, a.production)
|
||||
c.test.assertDependenciesEqual(c.test, c.production, b.test, a.production)
|
||||
c.production.assertDependenciesEqual(c.production, a.production)
|
||||
}
|
||||
|
||||
fun testCommonLibraryDoesNotDependOnPlatform() {
|
||||
val stdlibCommon = stdlibCommon()
|
||||
val stdlibJvm = stdlibJvm()
|
||||
val stdlibJs = stdlibJs()
|
||||
|
||||
val a = module("a")
|
||||
a.addDependency(stdlibCommon)
|
||||
a.addDependency(stdlibJvm)
|
||||
|
||||
val b = module("b")
|
||||
b.setUpPlatform(JsPlatforms.defaultJsPlatform)
|
||||
b.addDependency(stdlibCommon)
|
||||
b.addDependency(stdlibJs)
|
||||
|
||||
stdlibCommon.classes.assertAdditionalLibraryDependencies()
|
||||
stdlibJvm.classes.assertAdditionalLibraryDependencies(stdlibCommon.classes)
|
||||
stdlibJs.classes.assertAdditionalLibraryDependencies(stdlibCommon.classes)
|
||||
}
|
||||
|
||||
fun testScriptDependenciesForModule() {
|
||||
val a = module("a")
|
||||
val b = module("b")
|
||||
|
||||
with(createFileInModule(a, "script.kts").moduleInfo) {
|
||||
dependencies().contains(a.production)
|
||||
dependencies().contains(a.test)
|
||||
!dependencies().contains(b.production)
|
||||
}
|
||||
}
|
||||
|
||||
fun testScriptDependenciesForProject() {
|
||||
val a = module("a")
|
||||
|
||||
val script = createFileInProject("script.kts").moduleInfo
|
||||
|
||||
!script.dependencies().contains(a.production)
|
||||
!script.dependencies().contains(a.test)
|
||||
|
||||
script.dependencies().firstIsInstance<ScriptDependenciesInfo.ForFile>()
|
||||
}
|
||||
|
||||
fun testSdkForScript() {
|
||||
// The first known jdk will be used for scripting if there is no jdk in the project
|
||||
runWriteAction {
|
||||
addJdk(testRootDisposable, ::mockJdk6)
|
||||
addJdk(testRootDisposable, ::mockJdk9)
|
||||
|
||||
ProjectRootManager.getInstance(project).projectSdk = null
|
||||
}
|
||||
|
||||
val firstSDK = getProjectJdkTableSafe().allJdks.first()
|
||||
|
||||
with(createFileInProject("script.kts").moduleInfo) {
|
||||
dependencies().filterIsInstance<SdkInfo>().single { it.sdk == firstSDK }
|
||||
}
|
||||
}
|
||||
|
||||
fun testSdkForScriptProjectSdk() {
|
||||
runWriteAction {
|
||||
addJdk(testRootDisposable, ::mockJdk6)
|
||||
addJdk(testRootDisposable, ::mockJdk9)
|
||||
|
||||
ProjectRootManager.getInstance(project).projectSdk = mockJdk9()
|
||||
}
|
||||
|
||||
with(createFileInProject("script.kts").moduleInfo) {
|
||||
dependencies().filterIsInstance<SdkInfo>().single { it.sdk == mockJdk9() }
|
||||
}
|
||||
}
|
||||
|
||||
fun testSdkForScriptModuleSdk() {
|
||||
val a = module("a")
|
||||
|
||||
runWriteAction {
|
||||
addJdk(testRootDisposable, ::mockJdk6)
|
||||
addJdk(testRootDisposable, ::mockJdk9)
|
||||
|
||||
ProjectRootManager.getInstance(project).projectSdk = mockJdk6()
|
||||
with(ModuleRootManager.getInstance(a).modifiableModel) {
|
||||
sdk = mockJdk9()
|
||||
commit()
|
||||
}
|
||||
}
|
||||
|
||||
with(createFileInModule(a, "script.kts").moduleInfo) {
|
||||
dependencies().filterIsInstance<SdkInfo>().first { it.sdk == mockJdk9() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFileInModule(module: Module, fileName: String, inTests: Boolean = false): VirtualFile {
|
||||
val fileToCopyIO = createTempFile(fileName, "")
|
||||
|
||||
for (contentEntry in ModuleRootManager.getInstance(module).contentEntries) {
|
||||
for (sourceFolder in contentEntry.sourceFolders) {
|
||||
if (((!inTests && !sourceFolder.isTestSource) || (inTests && sourceFolder.isTestSource)) && sourceFolder.file != null) {
|
||||
return runWriteAction {
|
||||
getVirtualFile(fileToCopyIO).copy(this, sourceFolder.file!!, fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error("Couldn't find source folder in ${module.name}")
|
||||
}
|
||||
|
||||
private fun createFileInProject(fileName: String): VirtualFile {
|
||||
return runWriteAction {
|
||||
getVirtualFile(createTempFile(fileName, "")).copy(this, project.baseDir, fileName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Module.addDependency(
|
||||
other: Module,
|
||||
dependencyScope: DependencyScope = DependencyScope.COMPILE,
|
||||
exported: Boolean = false
|
||||
) = ModuleRootModificationUtil.addDependency(this, other, dependencyScope, exported)
|
||||
|
||||
private val VirtualFile.moduleInfo: IdeaModuleInfo
|
||||
get() {
|
||||
return PsiManager.getInstance(project).findFile(this)!!.getModuleInfo()
|
||||
}
|
||||
|
||||
private val Module.production: ModuleProductionSourceInfo
|
||||
get() = productionSourceInfo()!!
|
||||
|
||||
private val Module.test: ModuleTestSourceInfo
|
||||
get() = testSourceInfo()!!
|
||||
|
||||
private val LibraryEx.classes: LibraryInfo
|
||||
get() = object : LibraryInfo(project!!, this) {
|
||||
override val platform: TargetPlatform
|
||||
get() = kind.platform
|
||||
}
|
||||
|
||||
private fun module(name: String, hasProductionRoot: Boolean = true, hasTestRoot: Boolean = true): Module {
|
||||
return createModuleFromTestData(createTempDirectory().absolutePath, name, StdModuleTypes.JAVA, false).apply {
|
||||
if (hasProductionRoot)
|
||||
PsiTestUtil.addSourceContentToRoots(this, dir(), false)
|
||||
if (hasTestRoot)
|
||||
PsiTestUtil.addSourceContentToRoots(this, dir(), true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dir() = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(createTempDirectory())!!
|
||||
|
||||
private fun modules(name1: String = "a", name2: String = "b", name3: String = "c") = Triple(module(name1), module(name2), module(name3))
|
||||
|
||||
private fun IdeaModuleInfo.assertDependenciesEqual(vararg expected: IdeaModuleInfo) {
|
||||
Assert.assertEquals(expected.toList(), this.dependencies())
|
||||
}
|
||||
|
||||
private fun LibraryInfo.assertAdditionalLibraryDependencies(vararg expected: IdeaModuleInfo) {
|
||||
Assert.assertEquals(this, dependencies().first())
|
||||
val dependenciesWithoutSelf = this.dependencies().drop(1)
|
||||
UsefulTestCase.assertSameElements(dependenciesWithoutSelf, expected.toList())
|
||||
}
|
||||
|
||||
private fun ModuleSourceInfo.assertDependentsEqual(vararg expected: ModuleSourceInfo) {
|
||||
UsefulTestCase.assertSameElements(this.getDependentModules(), expected.toList())
|
||||
}
|
||||
|
||||
private fun stdlibCommon(): LibraryEx = projectLibrary(
|
||||
"kotlin-stdlib-common",
|
||||
ForTestCompileRuntime.stdlibCommonForTests().jarRoot,
|
||||
kind = CommonLibraryKind
|
||||
)
|
||||
|
||||
private fun stdlibJvm(): LibraryEx = projectLibrary("kotlin-stdlib", ForTestCompileRuntime.runtimeJarForTests().jarRoot)
|
||||
|
||||
private fun stdlibJs(): LibraryEx = projectLibrary(
|
||||
"kotlin-stdlib-js",
|
||||
ForTestCompileRuntime.runtimeJarForTests().jarRoot,
|
||||
kind = JSLibraryKind
|
||||
)
|
||||
|
||||
private fun Module.setUpPlatform(targetPlatform: TargetPlatform) {
|
||||
createMultiplatformFacetM3(
|
||||
platformKind = targetPlatform,
|
||||
dependsOnModuleNames = listOf(),
|
||||
pureKotlinSourceFolders = listOf(),
|
||||
)
|
||||
}
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
VfsRootAccess.allowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
VfsRootAccess.disallowRootAccess(KtTestUtil.getHomeDirectory())
|
||||
|
||||
super.tearDown()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -12,10 +12,10 @@ import java.io.File
|
||||
import java.nio.file.Path
|
||||
|
||||
abstract class AbstractConfigureKotlinInTempDirTest : AbstractConfigureKotlinTest() {
|
||||
override fun getProjectDirOrFile(): Path {
|
||||
override fun getProjectDirOrFile(isDirectoryBasedProject: Boolean): Path {
|
||||
val tempDir = FileUtil.generateRandomTemporaryPath()
|
||||
FileUtil.createTempDirectory("temp", null)
|
||||
myFilesToDelete.add(tempDir.toPath())
|
||||
getTempDir().scheduleDelete(tempDir.toPath())
|
||||
|
||||
FileUtil.copyDir(File(projectRoot), tempDir)
|
||||
|
||||
@@ -35,4 +35,4 @@ abstract class AbstractConfigureKotlinInTempDirTest : AbstractConfigureKotlinTes
|
||||
|
||||
return File(projectFilePath).toPath()
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user