Compare commits

...

7 Commits

Author SHA1 Message Date
Yan Zhulanow
fa8745978a ~ 2021-03-29 17:28:37 +09:00
Yan Zhulanow
e5951a7b54 ~~~~ switch 203 ~~~~ 2021-03-26 21:25:28 +09:00
Yan Zhulanow
038a8b9b23 Return 203 bunch back 2021-03-26 21:25:22 +09:00
Yan Zhulanow
05174c7255 Update 203 bunch 2021-03-26 21:24:30 +09:00
Yan Zhulanow
1789d0116b Add verification metadata for IntelliJ 2020.3 2021-03-26 21:21:10 +09:00
Yan Zhulanow
d54699f6a5 Fix receiver parameter name for property accessors
This partially fixes the following test in kotlin-ide:
- SimpleKotlinRenderLogTest.testReceiverFun()
2021-03-25 20:26:20 +09:00
Yan Zhulanow
3f0aaf4454 IDE: Publish JS IR klib artifact 2021-03-25 20:26:19 +09:00
131 changed files with 12669 additions and 376 deletions

1
.bunch
View File

@@ -1,4 +1,5 @@
202
203_202
201
as41_201
as42

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -255,7 +255,7 @@ class BinaryJavaClass(
}
}
override fun visitPermittedSubtypeExperimental(permittedSubtype: String?) {
permittedTypes.addIfNotNull(permittedSubtype?.convertInternalNameToClassifierType())
override fun visitPermittedSubclass(permittedSubclass: String?) {
permittedTypes.addIfNotNull(permittedSubclass?.convertInternalNameToClassifierType())
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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

View File

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

View File

@@ -16,3 +16,5 @@ sourceSets {
"test" {}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

@@ -18,6 +18,9 @@ sourceSets {
"test" {}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
sourcesJar()
javadocJar()

View File

@@ -86,6 +86,9 @@ sourceSets {
"test" { }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
projectTest(parallel = true) {
workingDir = rootDir
useAndroidSdk()

View File

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

View File

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

View File

@@ -44,3 +44,6 @@ sourceSets {
}
"test" {}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

@@ -37,6 +37,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
projectTest(parallel = true) {
dependsOn(":dist")
workingDir = project.rootDir

View File

@@ -34,6 +34,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
projectTest(parallel = true) {
dependsOn(":dist")
workingDir = rootDir

View File

@@ -44,6 +44,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
projectTest {
dependsOn(":dist")
workingDir = rootDir

View File

@@ -45,6 +45,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
projectTest {
dependsOn(":dist")
workingDir = rootDir

View File

@@ -35,6 +35,9 @@ sourceSets {
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
testsJar()
projectTest {

View File

@@ -14,3 +14,6 @@ sourceSets {
"main" { projectDefault() }
"test" { }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

@@ -85,6 +85,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
testsJar()
projectTest(parallel = true) {

View File

@@ -95,6 +95,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
testsJar()
projectTest(parallel = false) {

View File

@@ -14,4 +14,7 @@ dependencies {
sourceSets {
"main" { projectDefault() }
"test" { none() }
}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

@@ -21,4 +21,7 @@ sourceSets {
"test" {}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
runtimeJar()

View File

@@ -32,6 +32,9 @@ sourceSets {
"test" { none() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
configureFormInstrumentation()
runtimeJar()

View File

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

View File

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

View File

@@ -98,6 +98,9 @@ if (Ide.IJ()) {
}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
testsJar()
projectTest(parallel = true) {

View File

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

View File

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

View File

@@ -27,6 +27,9 @@ sourceSets {
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
configureFormInstrumentation()
runtimeJar {

View File

@@ -57,6 +57,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
testsJar()
projectTest {

View File

@@ -23,4 +23,7 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
testsJar()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -21,6 +21,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
projectTest(parallel = true) {
dependsOn(":dist")
workingDir = rootDir

View File

@@ -25,4 +25,7 @@ dependencies {
sourceSets {
"main" { projectDefault() }
"test" { none() }
}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

@@ -19,4 +19,7 @@ dependencies {
sourceSets {
"main" { projectDefault() }
"test" { none() }
}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

@@ -22,4 +22,7 @@ dependencies {
sourceSets {
"main" { projectDefault() }
"test" { none() }
}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

@@ -21,3 +21,6 @@ sourceSets {
"main" { projectDefault() }
"test" { none() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

@@ -46,6 +46,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
projectTest(parallel = true) {
dependsOn(":dist")
workingDir = rootDir

View File

@@ -23,4 +23,7 @@ dependencies {
sourceSets {
"main" { projectDefault() }
"test" { none() }
}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

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

View File

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

View File

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

View File

@@ -14,3 +14,5 @@ sourceSets {
"test" {}
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String

View File

@@ -52,6 +52,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
runtimeJar()
sourcesJar()

View File

@@ -45,6 +45,9 @@ sourceSets {
"test" { projectDefault() }
}
jvmTarget = "11"
javaHome = rootProject.extra["JDK_11"] as String
projectTest(parallel = true) {
dependsOn(":dist")
workingDir = rootDir

View File

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

View File

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

View File

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

View 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())
}
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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 = "&nbsp;&nbsp;&nbsp;&nbsp;{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())
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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