Compare commits

...

28 Commits
rc ... beta4

Author SHA1 Message Date
Nikolay Krasko
2dd1f1569b Dummy change to see build in TeamCity dependencies 2016-01-19 14:22:15 +03:00
Zalim Bashorov
2f8b891552 Don't fail when create IncrementalCacheImpl for target without output directory, and fail when try to use this info instead.
#KT-10505 Fixed
(cherry picked from commit c1dbfee)
2016-01-18 18:06:51 +03:00
Zalim Bashorov
d31a066145 Don't fail when output directory not specified for "friend" build target
#KT-10505 Fixed
(cherry picked from commit d9af947)
2016-01-18 18:06:41 +03:00
Zalim Bashorov
9de637a159 Report error when output directory not specified for build target
#KT-10505 Fixed
(cherry picked from commit 3df091e)
2016-01-18 18:06:32 +03:00
Natalia Ukhorskaya
43fcadae3f Gradle plugin: fix compatibility with android-gradle plugin 2.0.0-alpha5
#KT-10676 Fixed
(cherry picked from commit d4fcb59)
2016-01-18 17:36:35 +03:00
Nikolay Krasko
53f92f35d4 Remove assert that isn't valid in UpSource (UP-5742) 2016-01-12 21:41:54 +03:00
Michael Bogdanov
b4840bddc5 Always generate ACC_SUPER flag for all classes; Fix for KT-10260: java.lang.VerifyError in Android 4.x when Instant Run is used
#KT-10260 Fixed
(cherry picked from commit 0274ce4)
2016-01-11 13:02:34 +03:00
Pavel V. Talanov
3b253d10f3 Fix a problem caused by getting project using an invalid psi element 2015-12-23 16:47:40 +03:00
Yan Zhulanow
19c3382a19 Always compile Android projects without JDK in classpath #KT-10479 2015-12-23 16:43:47 +03:00
Dmitry Petrov
65a1c7b040 Fix KT-10472: compare all overloads including varargs in a single pass. 2015-12-22 17:10:55 +03:00
Stanislav Erokhin
0cffd955ea Hack for unavailable archive.apache.org: use bintray.com instead
(cherry picked from commit de6f520)
2015-12-22 16:47:43 +03:00
Nikolay Krasko
3847dd9794 Make add test lib quick-fix applicable only when there is unresolved import 2015-12-22 16:24:08 +03:00
Nikolay Krasko
bc5911e64b Add library for Gradle 2015-12-22 16:24:07 +03:00
Nikolay Krasko
6f96192e2f Determine maven library version from kotlin-stdlib 2015-12-22 16:24:07 +03:00
Nikolay Krasko
9f378345fc Add libraries to maven 2015-12-22 16:24:07 +03:00
Nikolay Krasko
760052b917 Add kotlin-test.jar to classpath quickfix 2015-12-22 16:24:07 +03:00
Sergey Mashkov
035fe187c1 kotlin-test: exclude OnlyInpuType from dist kotlin-test as well 2015-12-21 15:50:46 +03:00
Sergey Mashkov
e1a0caa27b kotlin-test: exclude OnlyInputTypes annotation from jar 2015-12-21 15:50:38 +03:00
Sergey Mashkov
e0061f5f37 rename kotlin.test to kotlin-test 2015-12-21 15:50:27 +03:00
Nikolay Krasko
128ddd5237 Enable version auto-increment and bootstrapping 2015-12-21 13:52:18 +03:00
Dmitry Petrov
b8094b2073 Prohibit functions (and constructors) with multiple vararg parameters.
(cherry picked from commit fab072e)
2015-12-21 13:28:27 +03:00
Andrey Breslav
e3924564ed Reserve "async* {}", extend the quick-fix 2015-12-21 07:07:15 +03:00
Andrey Breslav
3bb8d69760 Minor. Additional test for "async {}" 2015-12-21 07:07:15 +03:00
Stanislav Erokhin
c926c135ca Completion fix for reserved 'async' syntax 2015-12-21 07:07:15 +03:00
Nikolay Krasko
8714672ced Quick fix for deprecated async syntax 2015-12-21 07:07:15 +03:00
Ilya Gorbunov
bbc8941d76 Deprecate IndexingIterable and IndexingIterator and provide Iterator.withIndex() instead of the latter. 2015-12-19 09:58:28 +03:00
Ilya Gorbunov
2a18ab2d76 Deprecate some top-level constants to make 'em private later. 2015-12-19 09:58:26 +03:00
Ilya Chernikov
280c41a64d Working around cancellation-related exception in case of different versions of daemon and client 2015-12-18 22:20:59 +01:00
107 changed files with 1256 additions and 170 deletions

View File

@@ -969,7 +969,7 @@
<target name="pack-kotlin-test">
<pack-runtime-jar jar-name="kotlin-test.jar" implementation-title="${manifest.impl.title.kotlin.test}">
<jar-content>
<fileset dir="${output}/classes/kotlin.test" includes="**/*"/>
<fileset dir="${output}/classes/kotlin.test" includes="**/*" excludes="kotlin/internal/OnlyInputTypes*,kotlin/internal"/>
</jar-content>
</pack-runtime-jar>
</target>
@@ -1077,4 +1077,5 @@
<target name="build-bootstrap-artifacts" depends="dist,zip-compiler"/>
<target name="build-artifacts" depends="dist,zip-compiler,kotlin-for-upsource,zip-test-data"/>
<!-- Dummy change to see build in TeamCity dependencies -->
</project>

View File

@@ -51,7 +51,7 @@ public class InterfaceImplBodyCodegen(
override fun generateDeclaration() {
v.defineClass(
myClass, V1_6, ACC_PUBLIC or ACC_FINAL,
myClass, V1_6, ACC_PUBLIC or ACC_FINAL or ACC_SUPER,
typeMapper.mapDefaultImpls(descriptor).internalName,
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
)

View File

@@ -297,8 +297,8 @@ public class MultifileClassCodegen(
}
companion object {
private val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL
private val OPEN_FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC
private val FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_FINAL or Opcodes.ACC_SUPER
private val OPEN_FACADE_CLASS_ATTRIBUTES = Opcodes.ACC_PUBLIC or Opcodes.ACC_SUPER
private fun getOnlyPackageFragment(packageFqName: FqName, files: Collection<KtFile>, bindingContext: BindingContext): PackageFragmentDescriptor? {
val fragments = SmartList<PackageFragmentDescriptor>()

View File

@@ -46,7 +46,7 @@ public class MultifileClassPartCodegen(
override fun generateDeclaration() {
v.defineClass(element, Opcodes.V1_6,
Opcodes.ACC_FINAL or Opcodes.ACC_SYNTHETIC,
Opcodes.ACC_FINAL or Opcodes.ACC_SYNTHETIC or Opcodes.ACC_SUPER,
filePartType.internalName,
null,
"java/lang/Object",

View File

@@ -63,7 +63,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
@Override
protected void generateDeclaration() {
v.defineClass(element, V1_6,
ACC_PUBLIC | ACC_FINAL,
ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
packagePartType.getInternalName(),
null,
"java/lang/Object",

View File

@@ -86,7 +86,7 @@ public class SamWrapperCodegen {
ClassBuilder cv = state.getFactory().newVisitor(JvmDeclarationOriginKt.OtherOrigin(erasedInterfaceFunction), asmType, file);
cv.defineClass(file,
V1_6,
ACC_FINAL,
ACC_FINAL | ACC_SUPER,
asmType.getInternalName(),
null,
OBJECT_TYPE.getInternalName(),

View File

@@ -88,7 +88,7 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
v.defineClass(scriptDeclaration,
V1_6,
ACC_PUBLIC,
ACC_PUBLIC | ACC_SUPER,
classType.getInternalName(),
null,
"java/lang/Object",

View File

@@ -47,7 +47,7 @@ public class MappingClassesForWhenByEnumCodegen {
cb.defineClass(
srcFile,
V1_6,
ACC_FINAL | ACC_SYNTHETIC | ACC_PUBLIC,
ACC_PUBLIC | ACC_FINAL | ACC_SUPER | ACC_SYNTHETIC,
mappingsClass.getInternalName(),
null,
OBJECT_TYPE.getInternalName(),

View File

@@ -16,8 +16,10 @@
package org.jetbrains.kotlin.daemon.client
import com.intellij.openapi.progress.ProcessCanceledException
import org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade
import org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface
import org.jetbrains.kotlin.daemon.common.RmiFriendlyCompilationCancelledException
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
import org.jetbrains.kotlin.incremental.components.LookupInfo
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -80,6 +82,13 @@ class CompilerCallbackServicesFacadeServer(
override fun lookupTracker_isDoNothing(): Boolean = lookupTracker_isDoNothing
override fun compilationCanceledStatus_checkCanceled() {
compilationCancelledStatus!!.checkCanceled()
try {
compilationCancelledStatus!!.checkCanceled()
}
catch (e: ProcessCanceledException) {
// avoid passing exceptions that may have different serialVersionUID on across rmi border
// TODO: doublecheck whether we need to distinguish different cancellation exceptions
throw RmiFriendlyCompilationCancelledException()
}
}
}

View File

@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.daemon.common
import org.jetbrains.kotlin.incremental.components.LookupInfo
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
import org.jetbrains.kotlin.modules.TargetId
import java.io.Serializable
import java.rmi.Remote
import java.rmi.RemoteException
@@ -81,7 +82,13 @@ interface CompilerCallbackServicesFacade : Remote {
// ----------------------------------------------------
// CompilationCanceledStatus
@Throws(RemoteException::class)
@Throws(RemoteException::class, RmiFriendlyCompilationCancelledException::class)
fun compilationCanceledStatus_checkCanceled(): Unit
}
class RmiFriendlyCompilationCancelledException: Exception(), Serializable {
companion object {
private val serialVersionUID: Long = 8228357578L // just a random number, but should never be changed to avoid deserialization problems
}
}

View File

@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade
import org.jetbrains.kotlin.daemon.common.DummyProfiler
import org.jetbrains.kotlin.daemon.common.Profiler
import org.jetbrains.kotlin.daemon.common.RmiFriendlyCompilationCancelledException
import org.jetbrains.kotlin.progress.CompilationCanceledException
import java.util.concurrent.TimeUnit
val CANCELED_STATUS_CHECK_THRESHOLD_NS = TimeUnit.MILLISECONDS.toNanos(100)
@@ -30,7 +32,12 @@ class RemoteCompilationCanceledStatusClient(val facade: CompilerCallbackServices
val curNanos = System.nanoTime()
if (curNanos - lastChecked > CANCELED_STATUS_CHECK_THRESHOLD_NS) {
profiler.withMeasure(this) {
facade.compilationCanceledStatus_checkCanceled()
try {
facade.compilationCanceledStatus_checkCanceled()
}
catch (e: RmiFriendlyCompilationCancelledException) {
throw CompilationCanceledException()
}
}
lastChecked = curNanos
}

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.cfg;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
@@ -285,6 +286,6 @@ public final class WhenChecker {
}
public static void checkReservedPrefix(@NotNull BindingTrace trace, @NotNull KtWhenExpression expression) {
KtPsiUtilKt.checkReservedPrefixWord(trace, expression.getWhenKeyword(), "sealed", "sealed when");
KtPsiUtilKt.checkReservedPrefixWord(trace, expression.getWhenKeyword(), "sealed", TokenSet.EMPTY, "sealed when");
}
}

View File

@@ -420,6 +420,8 @@ public interface Errors {
DiagnosticFactory0<KtParameter> USELESS_VARARG_ON_PARAMETER = DiagnosticFactory0.create(WARNING);
DiagnosticFactory0<KtDeclaration> MULTIPLE_VARARG_PARAMETERS = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
// Named parameters
DiagnosticFactory0<KtParameter> DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE = DiagnosticFactory0.create(ERROR, PARAMETER_DEFAULT_VALUE);

View File

@@ -234,6 +234,7 @@ public class DefaultErrorMessages {
MAP.put(ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE, "An anonymous function is not allowed to specify default values for its parameters");
MAP.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless");
MAP.put(MULTIPLE_VARARG_PARAMETERS, "Declarations with multiple vararg-parameters are prohibited");
MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties");
MAP.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here");

View File

@@ -241,11 +241,15 @@ public interface KtTokens {
TokenSet OPERATIONS = TokenSet.create(AS_KEYWORD, AS_SAFE, IS_KEYWORD, IN_KEYWORD, DOT, PLUSPLUS, MINUSMINUS, EXCLEXCL, MUL, PLUS,
MINUS, EXCL, DIV, PERC, LT, GT, LTEQ, GTEQ, EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR,
SAFE_ACCESS, ELVIS,
// MAP, FILTER,
RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ,
NOT_IN, NOT_IS,
IDENTIFIER);
TokenSet BINARY_OPERATIONS = TokenSet.create(AS_KEYWORD, AS_SAFE, IS_KEYWORD, IN_KEYWORD, MUL, PLUS,
MINUS, DIV, PERC, LT, GT, LTEQ, GTEQ, EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR,
ELVIS, RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ,
NOT_IN, NOT_IS);
TokenSet AUGMENTED_ASSIGNMENTS = TokenSet.create(PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ);
TokenSet ALL_ASSIGNMENTS = TokenSet.create(EQ, PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ);
}

View File

@@ -24,6 +24,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.codeInsight.CommentUtilCore;
import com.intellij.util.containers.ContainerUtil;
@@ -608,9 +609,21 @@ public class KtPsiUtil {
return prev;
}
/**
* Example:
* code: async* {}
* element = "{}"
* word = "async"
* suffixTokens = [+, -, *, /, %]
*
* result = async
*/
@Nullable
public static PsiElement getPreviousWord(@NotNull PsiElement element, @NotNull String word) {
public static PsiElement getPreviousWord(@NotNull PsiElement element, @NotNull String word, @NotNull TokenSet suffixTokens) {
PsiElement prev = prevLeafIgnoringWhitespaceAndComments(element);
if (prev != null && suffixTokens.contains(prev.getNode().getElementType())) {
prev = PsiTreeUtil.prevLeaf(prev, false);
}
if (prev != null && prev.getNode().getElementType() == KtTokens.IDENTIFIER && word.equals(prev.getText())) {
return prev;
}

View File

@@ -23,6 +23,7 @@ import com.intellij.psi.PsiParameter
import com.intellij.psi.PsiParameterList
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.tree.TokenSet
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
@@ -434,8 +435,8 @@ fun canPlaceAfterSimpleNameEntry(element: PsiElement?): Boolean {
return !BAD_NEIGHBOUR_FOR_SIMPLE_TEMPLATE_ENTRY_PATTERN.matches(entryText)
}
fun checkReservedPrefixWord(sink: DiagnosticSink, element: PsiElement, word: String, message: String) {
KtPsiUtil.getPreviousWord(element, word)?.let {
fun checkReservedPrefixWord(sink: DiagnosticSink, element: PsiElement, word: String, suffixTokens: TokenSet, message: String) {
KtPsiUtil.getPreviousWord(element, word, suffixTokens)?.let {
sink.report(Errors.UNSUPPORTED.on(it, message))
}
}

View File

@@ -130,6 +130,7 @@ class DeclarationsChecker(
declaration.checkTypeReferences()
modifiersChecker.checkModifiersForDeclaration(declaration, constructorDescriptor)
identifierChecker.checkDeclaration(declaration, trace)
checkVarargParameters(declaration, constructorDescriptor)
}
private fun checkModifiersAndAnnotationsInPackageDirective(file: KtFile) {
@@ -323,11 +324,13 @@ class DeclarationsChecker(
else if (aClass is KtEnumEntry) {
checkEnumEntry(aClass, classDescriptor)
}
for (memberDescriptor in classDescriptor.declaredCallableMembers) {
if (memberDescriptor.kind != CallableMemberDescriptor.Kind.DECLARATION) continue
val member = DescriptorToSourceUtils.descriptorToDeclaration(memberDescriptor) as? KtFunction
if (member != null && memberDescriptor is FunctionDescriptor) {
checkFunctionExposedType(member, memberDescriptor)
checkVarargParameters(member, memberDescriptor)
}
}
}
@@ -650,7 +653,16 @@ class DeclarationsChecker(
trace.report(IMPLICIT_NOTHING_RETURN_TYPE.on(nameIdentifier ?: function))
}
}
checkFunctionExposedType(function, functionDescriptor)
checkVarargParameters(function, functionDescriptor)
}
private fun checkVarargParameters(declaration: KtDeclaration, callableDescriptor: CallableDescriptor) {
val numberOfVarargParameters = callableDescriptor.valueParameters.count { it.varargElementType != null }
if (numberOfVarargParameters > 1) {
trace.report(MULTIPLE_VARARG_PARAMETERS.on(declaration))
}
}
private fun checkFunctionExposedType(function: KtFunction, functionDescriptor: FunctionDescriptor) {

View File

@@ -88,17 +88,9 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
CandidateCallWithArgumentMapping.create(candidateCall) { it.arguments.filter { it.getArgumentExpression() != null } }
}
val (varargCandidates, regularCandidates) = conflictingCandidates.partition { it.resultingDescriptor.hasVarargs }
val mostSpecificRegularCandidates = regularCandidates.selectMostSpecificCallsWithArgumentMapping(discriminateGenericDescriptors)
val mostSpecificCandidates = conflictingCandidates.selectMostSpecificCallsWithArgumentMapping(discriminateGenericDescriptors)
return when {
mostSpecificRegularCandidates.size > 1 ->
null
mostSpecificRegularCandidates.size == 1 ->
mostSpecificRegularCandidates.single()
else ->
varargCandidates.selectMostSpecificCallsWithArgumentMapping(discriminateGenericDescriptors).singleOrNull()
}
return mostSpecificCandidates.singleOrNull()
}
private fun <D : CallableDescriptor, K> Collection<CandidateCallWithArgumentMapping<D, K>>.selectMostSpecificCallsWithArgumentMapping(
@@ -139,7 +131,7 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
/**
* Returns `true` if `d1` is definitely not less specific than `d2`,
* `false` if `d1` is definitely less specific than `d2` or undecided.
* `false` otherwise.
*/
private fun <D : CallableDescriptor, K> compareCallsWithArgumentMapping(
call1: CandidateCallWithArgumentMapping<D, K>,
@@ -160,6 +152,11 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
return it
}
val hasVarargs1 = call1.resultingDescriptor.hasVarargs
val hasVarargs2 = call2.resultingDescriptor.hasVarargs
if (hasVarargs1 && !hasVarargs2) return false
if (!hasVarargs1 && hasVarargs2) return true
assert(call1.argumentsCount == call2.argumentsCount) {
"$call1 and $call2 have different number of explicit arguments"
}

View File

@@ -109,6 +109,9 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
if (!function.hasBody() && !function.hasModifier(KtTokens.EXTERNAL_KEYWORD)) {
context.trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor))
}
if (functionDescriptor.valueParameters.count { it.varargElementType != null } > 1) {
context.trace.report(MULTIPLE_VARARG_PARAMETERS.on(function))
}
if (isStatement) {
return createTypeInfo(components.dataFlowAnalyzer.checkStatementType(function, context), context)
@@ -159,7 +162,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
}
private fun checkReservedAsync(context: ExpressionTypingContext, expression: PsiElement) {
checkReservedPrefixWord(context.trace, expression, "async", "async block/lambda. Use 'async() { ... }' or 'async(fun...)'")
checkReservedPrefixWord(context.trace, expression, "async", KtTokens.BINARY_OPERATIONS, "async block/lambda. Use 'async() { ... }' or 'async(fun...)'")
}
private fun createFunctionLiteralDescriptor(

View File

@@ -0,0 +1,13 @@
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("Test")
fun foo() {
}
/*ACC_PUBLIC ACC_FINAL ACC_SUPER */
// 1 access flags 0x31
/*ACC_SYNTHETIC ACC_FINAL ACC_SUPER */
// 1 access flags 0x1030

View File

@@ -6,6 +6,7 @@ infix fun Any.async(f: () -> Unit) = f()
fun test(foo: Any) {
<!UNSUPPORTED!>async<!> { }
`async` { }
<!UNSUPPORTED!>async<!> /**/ { }
foo <!UNSUPPORTED!>async<!> { }
@@ -15,7 +16,30 @@ fun test(foo: Any) {
foo async ({ })
foo <!UNSUPPORTED!>async<!> fun () {}
foo `async` fun () {}
foo async (fun () {})
async (fun () {})
}
object async {
operator fun plus(f: () -> Unit) = f()
operator fun minus(f: () -> Unit) = f()
operator fun times(f: () -> Unit) = f()
operator fun div(f: () -> Unit) = f()
operator fun mod(f: () -> Unit) = f()
}
fun test() {
<!UNSUPPORTED!>async<!>+ {}
<!UNSUPPORTED!>async<!>- {}
<!UNSUPPORTED!>async<!>* {}
<!UNSUPPORTED!>async<!>/ {}
<!UNSUPPORTED!>async<!>% {}
async + {}
async - {}
async * {}
async / {}
async % {}
}

View File

@@ -1,5 +1,18 @@
package
public fun async(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public fun test(): kotlin.Unit
public fun test(/*0*/ foo: kotlin.Any): kotlin.Unit
public infix fun kotlin.Any.async(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public object async {
private constructor async()
public final operator fun div(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final operator fun minus(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public final operator fun mod(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public final operator fun plus(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public final operator fun times(/*0*/ f: () -> kotlin.Unit): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}

View File

@@ -33,11 +33,6 @@ annotation class Ann8(val p1: Array<String>,
val p3: Array<MyEnum>,
val p4: Array<Ann1>)
annotation class Ann9(vararg val p1: String,
vararg val p2: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>Class<*><!>,
vararg val p3: MyEnum,
vararg val p4: Ann1,
vararg val p5: Int)
// INCORRECT
annotation class InAnn1(val p1: <!NULLABLE_TYPE_OF_ANNOTATION_MEMBER!>Int?<!>,
@@ -64,6 +59,11 @@ annotation class InAnn10(val p1: <!NULLABLE_TYPE_OF_ANNOTATION_MEMBER!>String?<!
annotation class InAnn11(val p1: <!NULLABLE_TYPE_OF_ANNOTATION_MEMBER!>Ann1?<!>)
annotation class InAnn12(val p1: <!NULLABLE_TYPE_OF_ANNOTATION_MEMBER!>MyEnum?<!>)
annotation class InAnn13<!MULTIPLE_VARARG_PARAMETERS!>(vararg val p1: String,
vararg val p2: <!INVALID_TYPE_OF_ANNOTATION_MEMBER!>Class<*><!>,
vararg val p3: MyEnum,
vararg val p4: Ann1,
vararg val p5: Int)<!>
enum class MyEnum {
A

View File

@@ -83,18 +83,6 @@ package test {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class Ann9 : kotlin.Annotation {
public constructor Ann9(/*0*/ vararg p1: kotlin.String /*kotlin.Array<out kotlin.String>*/, /*1*/ vararg p2: java.lang.Class<*> /*kotlin.Array<out java.lang.Class<*>>*/, /*2*/ vararg p3: test.MyEnum /*kotlin.Array<out test.MyEnum>*/, /*3*/ vararg p4: test.Ann1 /*kotlin.Array<out test.Ann1>*/, /*4*/ vararg p5: kotlin.Int /*kotlin.IntArray*/)
public final val p1: kotlin.Array<out kotlin.String>
public final val p2: kotlin.Array<out java.lang.Class<*>>
public final val p3: kotlin.Array<out test.MyEnum>
public final val p4: kotlin.Array<out test.Ann1>
public final val p5: kotlin.IntArray
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class InAnn1 : kotlin.Annotation {
public constructor InAnn1(/*0*/ p1: kotlin.Int?, /*1*/ p3: kotlin.Short?, /*2*/ p4: kotlin.Long?, /*3*/ p5: kotlin.Double?, /*4*/ p6: kotlin.Float?, /*5*/ p7: kotlin.Char?, /*6*/ p8: kotlin.Boolean?)
public final val p1: kotlin.Int?
@@ -133,6 +121,18 @@ package test {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class InAnn13 : kotlin.Annotation {
public constructor InAnn13(/*0*/ vararg p1: kotlin.String /*kotlin.Array<out kotlin.String>*/, /*1*/ vararg p2: java.lang.Class<*> /*kotlin.Array<out java.lang.Class<*>>*/, /*2*/ vararg p3: test.MyEnum /*kotlin.Array<out test.MyEnum>*/, /*3*/ vararg p4: test.Ann1 /*kotlin.Array<out test.Ann1>*/, /*4*/ vararg p5: kotlin.Int /*kotlin.IntArray*/)
public final val p1: kotlin.Array<out kotlin.String>
public final val p2: kotlin.Array<out java.lang.Class<*>>
public final val p3: kotlin.Array<out test.MyEnum>
public final val p4: kotlin.Array<out test.Ann1>
public final val p5: kotlin.IntArray
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final annotation class InAnn4 : kotlin.Annotation {
public constructor InAnn4(/*0*/ p1: kotlin.Array<kotlin.Int>, /*1*/ p2: kotlin.Array<kotlin.Int>?)
public final val p1: kotlin.Array<kotlin.Int>

View File

@@ -0,0 +1,27 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED
<!MULTIPLE_VARARG_PARAMETERS!>fun test(vararg x1: Int, vararg x2: Int)<!> {
<!MULTIPLE_VARARG_PARAMETERS!>fun test2(vararg x1: Int, vararg x2: Int)<!> {
class LocalClass<!MULTIPLE_VARARG_PARAMETERS!>(vararg x1: Int, vararg x2: Int)<!> {
<!MULTIPLE_VARARG_PARAMETERS!>constructor(vararg x1: Int, vararg x2: Int, xx: Int)<!> {}
}
<!MULTIPLE_VARARG_PARAMETERS!>fun test3(vararg x1: Int, vararg x2: Int)<!> {}
}
}
<!MULTIPLE_VARARG_PARAMETERS!>fun Any.test(vararg x1: Int, vararg x2: Int, vararg x3: Int)<!> {}
interface I {
<!MULTIPLE_VARARG_PARAMETERS!>fun test(vararg x1: Int, vararg x2: Int)<!>
}
abstract class C<!MULTIPLE_VARARG_PARAMETERS!>(vararg x1: Int, vararg x2: Int, b: Boolean)<!> {
<!MULTIPLE_VARARG_PARAMETERS!>fun test(vararg x1: Int, vararg x2: Int)<!> {}
<!MULTIPLE_VARARG_PARAMETERS!>abstract fun test2(vararg x1: Int, vararg x2: Int)<!>
class CC<!MULTIPLE_VARARG_PARAMETERS!>(vararg x1: Int, vararg x2: Int, b: Boolean)<!> {
<!MULTIPLE_VARARG_PARAMETERS!>constructor(vararg x1: Int, vararg x2: Int)<!> {}
<!MULTIPLE_VARARG_PARAMETERS!>fun test(vararg x1: Int, vararg x2: Int)<!> {}
}
}

View File

@@ -0,0 +1,29 @@
package
public fun test(/*0*/ vararg x1: kotlin.Int /*kotlin.IntArray*/, /*1*/ vararg x2: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit
public fun kotlin.Any.test(/*0*/ vararg x1: kotlin.Int /*kotlin.IntArray*/, /*1*/ vararg x2: kotlin.Int /*kotlin.IntArray*/, /*2*/ vararg x3: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit
public abstract class C {
public constructor C(/*0*/ vararg x1: kotlin.Int /*kotlin.IntArray*/, /*1*/ vararg x2: kotlin.Int /*kotlin.IntArray*/, /*2*/ b: kotlin.Boolean)
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun test(/*0*/ vararg x1: kotlin.Int /*kotlin.IntArray*/, /*1*/ vararg x2: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit
public abstract fun test2(/*0*/ vararg x1: kotlin.Int /*kotlin.IntArray*/, /*1*/ vararg x2: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public final class CC {
public constructor CC(/*0*/ vararg x1: kotlin.Int /*kotlin.IntArray*/, /*1*/ vararg x2: kotlin.Int /*kotlin.IntArray*/)
public constructor CC(/*0*/ vararg x1: kotlin.Int /*kotlin.IntArray*/, /*1*/ vararg x2: kotlin.Int /*kotlin.IntArray*/, /*2*/ b: kotlin.Boolean)
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public final fun test(/*0*/ vararg x1: kotlin.Int /*kotlin.IntArray*/, /*1*/ vararg x2: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
public interface I {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract fun test(/*0*/ vararg x1: kotlin.Int /*kotlin.IntArray*/, /*1*/ vararg x2: kotlin.Int /*kotlin.IntArray*/): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}

View File

@@ -1,11 +1,11 @@
fun f(
<!MULTIPLE_VARARG_PARAMETERS!>fun f(
<!VAL_OR_VAR_ON_FUN_PARAMETER!>val<!> a: Int,
<!VAL_OR_VAR_ON_FUN_PARAMETER!>var<!> b: Int,
c: Int,
vararg <!VAL_OR_VAR_ON_FUN_PARAMETER!>var<!> d: Int,
vararg <!VAL_OR_VAR_ON_FUN_PARAMETER!>val<!> e: Int,
vararg f: Int
) {
)<!> {
a + b + c + d[0] + e[0] + f[0] // to avoid 'unused parameter'

View File

@@ -0,0 +1,13 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
object Right
object Wrong
interface A<T>
interface B<T> : A<T>
fun <T> foo(vararg t: T) = Wrong
fun <T> foo(t: A<T>) = Wrong
fun <T> foo(t: B<T>) = Right
fun test(b: B<Int>): Right = foo(b)

View File

@@ -0,0 +1,32 @@
package
public fun </*0*/ T> foo(/*0*/ t: A<T>): Wrong
public fun </*0*/ T> foo(/*0*/ t: B<T>): Right
public fun </*0*/ T> foo(/*0*/ vararg t: T /*kotlin.Array<out T>*/): Wrong
public fun test(/*0*/ b: B<kotlin.Int>): Right
public interface A</*0*/ T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface B</*0*/ T> : A<T> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object Right {
private constructor Right()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public object Wrong {
private constructor Wrong()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}

View File

@@ -0,0 +1,11 @@
interface Test {
fun a() {
}
}
// TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: Test$DefaultImpls
// FLAGS: ACC_PUBLIC, ACC_FINAL, ACC_SUPER

View File

@@ -0,0 +1,19 @@
enum class BigEnum {
ITEM1,
ITEM2
}
fun bar1(x : BigEnum) : String {
when (x) {
BigEnum.ITEM1 -> return "123"
BigEnum.ITEM2-> return "456"
}
return "-1";
}
// TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: MappingWhenKt$WhenMappings
// FLAGS: ACC_PUBLIC, ACC_SYNTHETIC, ACC_FINAL, ACC_SUPER

View File

@@ -0,0 +1,7 @@
fun foo() {
}
// TESTED_OBJECT_KIND: class
// TESTED_OBJECTS: SimpleFilePackageFacadeKt
// FLAGS: ACC_PUBLIC, ACC_FINAL, ACC_SUPER

View File

@@ -4224,6 +4224,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("mulitpleVarargParameters.kt")
public void testMulitpleVarargParameters() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/mulitpleVarargParameters.kt");
doTest(fileName);
}
@TestMetadata("MultiDeclarationErrors.kt")
public void testMultiDeclarationErrors() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/declarationChecks/MultiDeclarationErrors.kt");
@@ -13736,6 +13742,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("kt10472.kt")
public void testKt10472() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/kt10472.kt");
doTest(fileName);
}
@TestMetadata("numberOfDefaults.kt")
public void testNumberOfDefaults() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/numberOfDefaults.kt");

View File

@@ -305,6 +305,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
doTest(fileName);
}
@TestMetadata("superFlagInMultiFileFacade.kt")
public void testSuperFlagInMultiFileFacade() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/superFlagInMultiFileFacade.kt");
doTest(fileName);
}
@TestMetadata("topLevelFunWithDefaultArgs.kt")
public void testTopLevelFunWithDefaultArgs() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/topLevelFunWithDefaultArgs.kt");

View File

@@ -93,6 +93,18 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/writeFlags/class/accessFlags"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("defaultImpls.kt")
public void testDefaultImpls() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeFlags/class/accessFlags/defaultImpls.kt");
doTest(fileName);
}
@TestMetadata("mappingWhen.kt")
public void testMappingWhen() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeFlags/class/accessFlags/mappingWhen.kt");
doTest(fileName);
}
@TestMetadata("objectLiteral.kt")
public void testObjectLiteral() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeFlags/class/accessFlags/objectLiteral.kt");
@@ -122,6 +134,12 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeFlags/class/accessFlags/publicInterface.kt");
doTest(fileName);
}
@TestMetadata("simpleFilePackageFacade.kt")
public void testSimpleFilePackageFacade() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeFlags/class/accessFlags/simpleFilePackageFacade.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/writeFlags/class/deprecatedFlag")

View File

@@ -263,6 +263,7 @@ suppress.warning.for=Suppress ''{0}'' for {1} {2}
reflection.not.found=Reflection not found in the classpath
add.reflection.to.classpath=Add kotlin-reflect.jar to the classpath
add.test.to.classpath=Add kotlin-test.jar to the classpath
# Kotlin Compiler Settings Tab

View File

@@ -100,7 +100,6 @@ public object JarUserDataManager {
private fun storeUserData(counter: JarBooleanPropertyCounter, localJarFile: VirtualFile,
hasFileWithProperty: Boolean?, timestamp: Long? = null) {
assert(localJarFile.isInLocalFileSystem)
assert((timestamp == null) == (hasFileWithProperty == null)) { "Using empty timestamp is only allowed for storing not counted value" }
localJarFile.putUserData(counter.key,

View File

@@ -25,6 +25,7 @@ import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtTypeArgumentList
@@ -73,10 +74,10 @@ sealed class KotlinFunctionInsertHandler : KotlinCallableInsertHandler() {
val startOffset = context.startOffset
val element = context.file.findElementAt(startOffset) ?: return
addArguments(context, element)
addArguments(context, element, item)
}
private fun addArguments(context : InsertionContext, offsetElement : PsiElement) {
private fun addArguments(context: InsertionContext, offsetElement: PsiElement, item: LookupElement) {
val completionChar = context.getCompletionChar()
if (completionChar == '(') { //TODO: more correct behavior related to braces type
context.setAddCompletionChar(false)
@@ -122,6 +123,12 @@ sealed class KotlinFunctionInsertHandler : KotlinCallableInsertHandler() {
offset += 2
}
// insert additional brackets for reserved syntax: "async {}"
if (insertLambda && (item.`object` as? DeclarationLookupObject)?.name?.identifier == "async") {
document.insertString(offset, "()")
offset += 2
}
var openingBracketOffset = chars.indexOfSkippingSpace(openingBracket, offset)
var closeBracketOffset = openingBracketOffset?.let { chars.indexOfSkippingSpace(closingBracket, it + 1) }
var inBracketsShift = 0

View File

@@ -0,0 +1,7 @@
fun async(a: () -> Unit) {}
fun test() {
asy<caret>
}
// ELEMENT: async

View File

@@ -0,0 +1,7 @@
fun async(a: () -> Unit) {}
fun test() {
async() { <caret> }
}
// ELEMENT: async

View File

@@ -0,0 +1,7 @@
fun async (p: Int, a: () -> Unit) {}
fun test() {
asy<caret>
}
// ELEMENT: async

View File

@@ -0,0 +1,7 @@
fun async (p: Int, a: () -> Unit) {}
fun test() {
async(<caret>)
}
// ELEMENT: async

View File

@@ -0,0 +1,10 @@
fun asyFoo(a: () -> Unit) {}
fun async(a: () -> Unit) {}
fun test() {
asy<caret>Foo { }
}
// ELEMENT: async
// CHAR: '\t'

View File

@@ -0,0 +1,10 @@
fun asyFoo(a: () -> Unit) {}
fun async(a: () -> Unit) {}
fun test() {
async() { }
}
// ELEMENT: async
// CHAR: '\t'

View File

@@ -0,0 +1,10 @@
fun asyFoo(p: Int, a: () -> Unit) {}
fun async(q: Int, a: () -> Unit) {}
fun test() {
asy<caret>Foo(5) { }
}
// ELEMENT: async
// CHAR: '\t'

View File

@@ -0,0 +1,10 @@
fun asyFoo(p: Int, a: () -> Unit) {}
fun async(q: Int, a: () -> Unit) {}
fun test() {
async(<caret>5) { }
}
// ELEMENT: async
// CHAR: '\t'

View File

@@ -378,6 +378,39 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/WithArgsNonEmptyLambdaAfter.kt");
doTest(fileName);
}
@TestMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Async extends AbstractBasicCompletionHandlerTest {
public void testAllFilesPresentInAsync() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("AsyncSimple.kt")
public void testAsyncSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncSimple.kt");
doTest(fileName);
}
@TestMetadata("AsyncWithoutLambda.kt")
public void testAsyncWithoutLambda() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/AsyncWithoutLambda.kt");
doTest(fileName);
}
@TestMetadata("FromFooToAsync.kt")
public void testFromFooToAsync() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync.kt");
doTest(fileName);
}
@TestMetadata("FromFooToAsync2.kt")
public void testFromFooToAsync2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/highOrderFunctions/async/FromFooToAsync2.kt");
doTest(fileName);
}
}
}
@TestMetadata("idea/idea-completion/testData/handlers/basic/override")

View File

@@ -40,18 +40,25 @@ public class KotlinParenthesesSurrounder extends KotlinExpressionSurrounder {
@Nullable
@Override
public TextRange surroundExpression( @NotNull Project project, @NotNull Editor editor, @NotNull KtExpression expression) {
KtParenthesizedExpression parenthesizedExpression = (KtParenthesizedExpression) KtPsiFactoryKt
.KtPsiFactory(expression).createExpression("(a)");
KtExpression expressionWithoutParentheses = parenthesizedExpression.getExpression();
assert expressionWithoutParentheses != null : "JetExpression should exists for " + parenthesizedExpression.getText() + " expression";
expressionWithoutParentheses.replace(expression);
expression = (KtExpression) expression.replace(parenthesizedExpression);
public TextRange surroundExpression(@NotNull Project project, @NotNull Editor editor, @NotNull KtExpression expression) {
expression = surroundWithParentheses(expression);
CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(expression);
int offset = expression.getTextRange().getEndOffset();
return new TextRange(offset, offset);
}
@NotNull
public static KtExpression surroundWithParentheses(@NotNull KtExpression expression) {
KtParenthesizedExpression parenthesizedExpression =
(KtParenthesizedExpression) KtPsiFactoryKt.KtPsiFactory(expression).createExpression("(a)");
KtExpression expressionWithoutParentheses = parenthesizedExpression.getExpression();
assert expressionWithoutParentheses != null : "JetExpression should exists for " + parenthesizedExpression.getText() + " expression";
expressionWithoutParentheses.replace(expression);
expression = (KtExpression) expression.replace(parenthesizedExpression);
return expression;
}
}

View File

@@ -22,6 +22,8 @@ import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.DependencyScope;
import com.intellij.openapi.roots.ExternalLibraryDescriptor;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
@@ -33,6 +35,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.KotlinPluginUtil;
import org.jetbrains.kotlin.idea.framework.ui.ConfigureDialogWithModulesAndVersion;
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil;
import org.jetbrains.plugins.gradle.util.GradleConstants;
@@ -104,6 +107,83 @@ public abstract class KotlinWithGradleConfigurator implements KotlinProjectConfi
}
}
public static void addKotlinLibraryToModule(final Module module, final DependencyScope scope, final ExternalLibraryDescriptor libraryDescriptor) {
String gradleFilePath = getDefaultPathToBuildGradleFile(module);
final GroovyFile gradleFile = getBuildGradleFile(module.getProject(), gradleFilePath);
if (gradleFile != null && canConfigureFile(gradleFile)) {
new WriteCommandAction(gradleFile.getProject()) {
@Override
protected void run(@NotNull Result result) {
String groovyScope;
switch (scope) {
case COMPILE:
groovyScope = "compile";
break;
case TEST:
if (KotlinPluginUtil.isAndroidGradleModule(module)) {
// TODO we should add testCompile or androidTestCompile
groovyScope = "compile";
}
else {
groovyScope = "testCompile";
}
break;
case RUNTIME:
groovyScope = "runtime";
break;
case PROVIDED:
groovyScope = "compile";
break;
default:
groovyScope = "compile";
}
String dependencyString = String.format(
"%s \"%s:%s:%s\"",
groovyScope, libraryDescriptor.getLibraryGroupId(), libraryDescriptor.getLibraryArtifactId(), libraryDescriptor.getMaxVersion());
GrClosableBlock dependenciesBlock = getDependenciesBlock(gradleFile);
addLastExpressionInBlockIfNeeded(dependencyString, dependenciesBlock);
CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(gradleFile);
}
}.execute();
VirtualFile virtualFile = gradleFile.getVirtualFile();
if (virtualFile != null) {
showInfoNotification(gradleFile.getProject(), virtualFile.getPath() + " was modified");
}
}
}
@Nullable
public static String getKotlinStdlibVersion(@NotNull Module module) {
String gradleFilePath = getDefaultPathToBuildGradleFile(module);
GroovyFile gradleFile = getBuildGradleFile(module.getProject(), gradleFilePath);
if (gradleFile == null) return null;
String versionProperty = "$kotlin_version";
GrClosableBlock block = getBuildScriptBlock(gradleFile);
if (block.getText().contains("ext.kotlin_version = ")) {
return versionProperty;
}
GrStatement[] dependencies = getDependenciesBlock(gradleFile).getStatements();
String stdlibArtifactPrefix = "org.jetbrains.kotlin:kotlin-stdlib:";
for (GrStatement dependency : dependencies) {
String dependencyText = dependency.getText();
int startIndex = dependencyText.indexOf(stdlibArtifactPrefix) + stdlibArtifactPrefix.length();
int endIndex = dependencyText.length() - 1;
if (startIndex != -1 && endIndex != -1) {
return dependencyText.substring(startIndex, endIndex);
}
}
return null;
}
private void addElements(@NotNull GroovyFile file, @NotNull String version) {
GrClosableBlock buildScriptBlock = getBuildScriptBlock(file);
addFirstExpressionInBlockIfNeeded(VERSION.replace(VERSION_TEMPLATE, version), buildScriptBlock);
@@ -180,7 +260,7 @@ public abstract class KotlinWithGradleConfigurator implements KotlinProjectConfi
protected void changeGradleFile(@NotNull final GroovyFile groovyFile, @NotNull final String version) {
new WriteCommandAction(groovyFile.getProject()) {
@Override
protected void run(Result result) {
protected void run(@NotNull Result result) {
addElements(groovyFile, version);
CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(groovyFile);
@@ -258,7 +338,6 @@ public abstract class KotlinWithGradleConfigurator implements KotlinProjectConfi
if (allExpressions != null) {
for (GrMethodCallExpression expression : allExpressions) {
GrExpression invokedExpression = expression.getInvokedExpression();
if (invokedExpression == null) continue;
if (expression.getClosureArguments().length == 0) continue;
String expressionText = invokedExpression.getText();
@@ -293,7 +372,7 @@ public abstract class KotlinWithGradleConfigurator implements KotlinProjectConfi
if (applyStatement == null) return null;
for (GrApplicationStatement callExpression : applyStatement) {
GrExpression invokedExpression = callExpression.getInvokedExpression();
if (invokedExpression != null && invokedExpression.getText().equals("apply")) {
if (invokedExpression.getText().equals("apply")) {
return callExpression;
}
}

View File

@@ -72,4 +72,9 @@ public class JavaRuntimePresentationProvider extends LibraryPresentationProvider
public static VirtualFile getRuntimeSrcJar(@NotNull Library library) {
return getRuntimeSrcJar(Arrays.asList(library.getFiles(OrderRootType.SOURCES)));
}
@Nullable
public static VirtualFile getTestJar(@NotNull Library library) {
return LibraryUtils.getJarFile(Arrays.asList(library.getFiles(OrderRootType.CLASSES)), PathUtil.KOTLIN_TEST_JAR);
}
}

View File

@@ -0,0 +1,215 @@
/*
* 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.inspections
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ExternalLibraryDescriptor
import com.intellij.openapi.roots.JavaProjectModelModificationService
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.KotlinPluginUtil
import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtils
import org.jetbrains.kotlin.idea.configuration.KotlinJavaModuleConfigurator
import org.jetbrains.kotlin.idea.configuration.KotlinProjectConfigurator
import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator
import org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.createIntentionForFirstParentOfType
import org.jetbrains.kotlin.idea.versions.KotlinRuntimeLibraryUtil
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtImportDirective
import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.io.File
public class AddReflectionQuickFix(element: KtElement) : AddKotlinLibQuickFix(element) {
override fun getText() = KotlinBundle.message("add.reflection.to.classpath")
override fun getFamilyName() = text
override fun libraryPath(): String = PathUtil.KOTLIN_JAVA_REFLECT_JAR
override fun getLibFile(): File = PathUtil.getKotlinPathsForIdeaPlugin().reflectPath
override fun hasLibJarInLibrary(library: Library): Boolean = JavaRuntimePresentationProvider.getReflectJar(library) != null
override fun getLibraryDescriptor(module: Module) = MavenExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-reflect",
AddKotlinLibQuickFix.getKotlinStdlibVersion(module))
companion object : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic) = diagnostic.createIntentionForFirstParentOfType(::AddReflectionQuickFix)
}
}
public class AddTestLibQuickFix(element: KtElement) : AddKotlinLibQuickFix(element) {
override fun getText() = KotlinBundle.message("add.test.to.classpath")
override fun getFamilyName() = text
override fun libraryPath(): String = PathUtil.KOTLIN_TEST_JAR
override fun getLibFile(): File = PathUtil.getKotlinPathsForIdeaPlugin().kotlinTestPath
override fun hasLibJarInLibrary(library: Library): Boolean = JavaRuntimePresentationProvider.getTestJar(library) != null
override fun getLibraryDescriptor(module: Module) = MavenExternalLibraryDescriptor("org.jetbrains.kotlin", "kotlin-test",
AddKotlinLibQuickFix.getKotlinStdlibVersion(module))
companion object : KotlinSingleIntentionActionFactory() {
val KOTLIN_TEST_UNRESOLVED = setOf(
"Asserter", "assertFailsWith", "currentStackTrace", "failsWith", "todo", "assertEquals",
"assertFails", "assertNot", "assertNotEquals", "assertNotNull", "assertNull", "assertTrue", "expect", "fail", "fails")
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val unresolvedReference = Errors.UNRESOLVED_REFERENCE.cast(diagnostic)
if (PsiTreeUtil.getParentOfType(diagnostic.psiElement, KtImportDirective::class.java) != null) return null
val unresolvedText = unresolvedReference.a.text
if (unresolvedText in KOTLIN_TEST_UNRESOLVED) {
val ktFile = (diagnostic.psiElement.containingFile as? KtFile) ?: return null
val exactImportFqName = FqName("kotlin.test.$unresolvedText")
val kotlinTestAllUnder = FqName("kotlin.test")
var hasExactImport = false
var hasKotlinTestAllUnder = false
for (importDirective in ktFile.importDirectives.filter { it.text.contains("kotlin.test.") }) {
if (importDirective.importedFqName == exactImportFqName) {
hasExactImport = true
break
}
if (importDirective.importedFqName == kotlinTestAllUnder && importDirective.isAllUnder) {
hasKotlinTestAllUnder = true
break
}
}
if (hasExactImport || hasKotlinTestAllUnder) {
return diagnostic.createIntentionForFirstParentOfType(::AddTestLibQuickFix)
}
}
return null
}
}
}
public abstract class AddKotlinLibQuickFix(element: KtElement) : KotlinQuickFixAction<KtElement>(element) {
protected abstract fun libraryPath(): String
protected abstract fun getLibFile(): File
protected abstract fun hasLibJarInLibrary(library: Library): Boolean
protected abstract fun getLibraryDescriptor(module: Module): MavenExternalLibraryDescriptor
class MavenExternalLibraryDescriptor(groupId: String, artifactId: String, version: String) :
ExternalLibraryDescriptor(groupId, artifactId, version, version) {
override fun getLibraryClassesRoots(): List<String> = emptyList()
}
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val module = ProjectRootManager.getInstance(project).fileIndex.getModuleForFile(element.containingFile.virtualFile)
if (module != null) {
if (KotlinPluginUtil.isMavenModule(module)) {
val scope = OrderEntryFix.suggestScopeByLocation(module, element)
JavaProjectModelModificationService.getInstance(project).addDependency(module, getLibraryDescriptor(module), scope)
return
}
if (KotlinPluginUtil.isGradleModule(module) || KotlinPluginUtil.isAndroidGradleModule(module)) {
val scope = OrderEntryFix.suggestScopeByLocation(module, element)
KotlinWithGradleConfigurator.addKotlinLibraryToModule(module, scope, getLibraryDescriptor(module))
return
}
}
val libFile = getLibFile()
if (!libFile.exists()) return
val configurator = Extensions.getExtensions(KotlinProjectConfigurator.EP_NAME)
.firstIsInstanceOrNull<KotlinJavaModuleConfigurator>() ?: return
for (library in KotlinRuntimeLibraryUtil.findKotlinLibraries(project)) {
val runtimeJar = JavaRuntimePresentationProvider.getRuntimeJar(library) ?: continue
if (hasLibJarInLibrary(library)) continue
val model = library.modifiableModel
val libFilesDir = VfsUtilCore.virtualToIoFile(runtimeJar).parent
val libIoFile = File(libFilesDir, libraryPath())
if (libIoFile.exists()) {
model.addRoot(VfsUtil.getUrlForLibraryRoot(libIoFile), OrderRootType.CLASSES)
}
else {
val copied = configurator.copyFileToDir(project, libFile, libFilesDir)!!
model.addRoot(VfsUtil.getUrlForLibraryRoot(copied), OrderRootType.CLASSES)
}
model.commit()
ConfigureKotlinInProjectUtils.showInfoNotification(
project, "${libraryPath()} was added to the library ${library.name}")
}
}
companion object {
fun getKotlinStdlibVersion(module: Module): String {
if (KotlinPluginUtil.isMavenModule(module)) {
val mavenVersion = getMavenKotlinStdlibVersion(module)
if (mavenVersion != null) {
return mavenVersion
}
}
else if (KotlinPluginUtil.isGradleModule(module) || KotlinPluginUtil.isAndroidGradleModule(module)) {
val gradleVersion = KotlinWithGradleConfigurator.getKotlinStdlibVersion(module)
if (gradleVersion != null) {
return gradleVersion
}
}
val pluginVersion = KotlinRuntimeLibraryUtil.bundledRuntimeVersion()
if ("@snapshot@" == pluginVersion) {
return "0.1-SNAPSHOT"
}
return pluginVersion
}
fun getMavenKotlinStdlibVersion(module: Module): String? {
LibrariesContainerFactory.createContainer(module).allLibraries.forEach { library ->
val libName = library.name
if (libName != null && libName.contains("org.jetbrains.kotlin:kotlin-stdlib")) {
return libName.substringAfterLast(":")
}
}
return null
}
}
}

View File

@@ -1,79 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.inspections
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VfsUtilCore
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtils
import org.jetbrains.kotlin.idea.configuration.KotlinJavaModuleConfigurator
import org.jetbrains.kotlin.idea.configuration.KotlinProjectConfigurator
import org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
import org.jetbrains.kotlin.idea.quickfix.quickfixUtil.createIntentionForFirstParentOfType
import org.jetbrains.kotlin.idea.versions.KotlinRuntimeLibraryUtil
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.io.File
public class AddReflectionQuickFix(element: KtElement) : KotlinQuickFixAction<KtElement>(element) {
override fun getText() = KotlinBundle.message("add.reflection.to.classpath")
override fun getFamilyName() = getText()
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val pluginReflectJar = PathUtil.getKotlinPathsForIdeaPlugin().getReflectPath()
if (!pluginReflectJar.exists()) return
val configurator = Extensions.getExtensions(KotlinProjectConfigurator.EP_NAME)
.firstIsInstanceOrNull<KotlinJavaModuleConfigurator>() ?: return
for (library in KotlinRuntimeLibraryUtil.findKotlinLibraries(project)) {
val runtimeJar = JavaRuntimePresentationProvider.getRuntimeJar(library) ?: continue
if (JavaRuntimePresentationProvider.getReflectJar(library) != null) continue
val model = library.getModifiableModel()
val libFilesDir = VfsUtilCore.virtualToIoFile(runtimeJar).getParent()
val reflectIoFile = File(libFilesDir, PathUtil.KOTLIN_JAVA_REFLECT_JAR)
if (reflectIoFile.exists()) {
model.addRoot(VfsUtil.getUrlForLibraryRoot(reflectIoFile), OrderRootType.CLASSES)
}
else {
val copied = configurator.copyFileToDir(project, pluginReflectJar, libFilesDir)!!
model.addRoot(VfsUtil.getUrlForLibraryRoot(copied), OrderRootType.CLASSES)
}
model.commit()
ConfigureKotlinInProjectUtils.showInfoNotification(project,
"${PathUtil.KOTLIN_JAVA_REFLECT_JAR} was added to the library ${library.getName()}"
)
}
}
companion object : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic) = diagnostic.createIntentionForFirstParentOfType(::AddReflectionQuickFix)
}
}

View File

@@ -98,7 +98,8 @@ public class KotlinCleanupInspection(): LocalInspectionTool(), CleanupLocalInspe
Errors.CALLABLE_REFERENCE_TO_MEMBER_OR_EXTENSION_WITH_EMPTY_LHS,
Errors.DEPRECATED_TYPE_PARAMETER_SYNTAX,
Errors.MISPLACED_TYPE_PARAMETER_CONSTRAINTS,
Errors.COMMA_IN_WHEN_CONDITION_WITHOUT_ARGUMENT
Errors.COMMA_IN_WHEN_CONDITION_WITHOUT_ARGUMENT,
Errors.UNSUPPORTED
)
private fun Diagnostic.isObsoleteLabel(): Boolean {

View File

@@ -28,7 +28,10 @@ import org.jetbrains.kotlin.psi.KtFile
abstract class KotlinQuickFixAction<T : PsiElement>(protected val element: T) : IntentionAction {
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
return element.isValid && (file.manager.isInProject(file) || file is KtCodeFragment) && (file is KtFile)
return element.isValid &&
!element.project.isDisposed &&
(file.manager.isInProject(file) || file is KtCodeFragment) &&
(file is KtFile)
}
override final fun invoke(project: Project, editor: Editor?, file: PsiFile) {

View File

@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
import org.jetbrains.kotlin.idea.inspections.AddModifierFixFactory
import org.jetbrains.kotlin.idea.inspections.AddReflectionQuickFix
import org.jetbrains.kotlin.idea.inspections.AddTestLibQuickFix
import org.jetbrains.kotlin.idea.inspections.InfixCallFix
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.*
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromCallWithConstructorCalleeActionFactory
@@ -125,6 +126,8 @@ public class QuickFixRegistrar : QuickFixContributor {
REPEATED_MODIFIER.registerFactory(removeModifierFactory)
UNRESOLVED_REFERENCE.registerFactory(AutoImportFix)
UNRESOLVED_REFERENCE.registerFactory(AddTestLibQuickFix)
UNRESOLVED_REFERENCE_WRONG_RECEIVER.registerFactory(AutoImportFix)
FUNCTION_EXPECTED.registerFactory(MissingInvokeAutoImportFix)
@@ -356,5 +359,7 @@ public class QuickFixRegistrar : QuickFixContributor {
DEPRECATED_UNARY_PLUS_MINUS.registerFactory(DeprecatedFunctionConventionFix)
COMMA_IN_WHEN_CONDITION_WITHOUT_ARGUMENT.registerFactory(CommaInWhenConditionWithoutArgumentFix)
UNSUPPORTED.registerFactory(UnsupportedAsyncFix)
}
}

View File

@@ -0,0 +1,70 @@
/*
* 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.quickfix
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.idea.codeInsight.surroundWith.expression.KotlinParenthesesSurrounder
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
public class UnsupportedAsyncFix(val psiElement: PsiElement): KotlinQuickFixAction<PsiElement>(psiElement), CleanupFix {
override fun getFamilyName(): String = "Migrate unsupported async syntax"
override fun getText(): String = familyName
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
if (element is KtBinaryExpression) {
if (element.operationToken != KtTokens.IDENTIFIER) {
// async+ {}
element.addBefore(KtPsiFactory(element).createWhiteSpace(), element.operationReference)
}
else if (element.right != null) {
// foo async {}
KotlinParenthesesSurrounder.surroundWithParentheses(element.right!!)
}
}
if (element is KtCallExpression) {
val ktExpression = element.calleeExpression ?: return
// Add after "async" reference in call
element.addAfter(KtPsiFactory(element).createCallArguments("()"), ktExpression)
}
}
companion object : KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
if (diagnostic.psiElement.text != "async" ||
!Errors.UNSUPPORTED.cast(diagnostic).a.startsWith("async block/lambda")) return null
// Identifier -> Expression -> Call (normal call) or Identifier -> Operation Reference -> Binary Expression (for infix usage)
val grand = diagnostic.psiElement.parent.parent
if (grand is KtBinaryExpression || grand is KtCallExpression) {
return UnsupportedAsyncFix(grand)
}
return null
}
}
}

View File

@@ -76,3 +76,28 @@ val x = C() willBeInfix 1
fun infixTest() {
arrayListOf(1, 2, 3) map { it }
}
fun async(f: () -> Unit) {}
infix fun Any.async(f: () -> Unit) {}
object async {
operator fun times(f: () -> Unit) = f()
}
fun test(foo: Any) {
async { }
async /**/ { }
foo async { }
async() { }
async({ })
foo async ({ })
foo async fun () {}
foo async (fun () {})
async (fun () {})
async* {}
}

View File

@@ -75,3 +75,28 @@ val x = C() willBeInfix 1
fun infixTest() {
arrayListOf(1, 2, 3).map { it }
}
fun async(f: () -> Unit) {}
infix fun Any.async(f: () -> Unit) {}
object async {
operator fun times(f: () -> Unit) = f()
}
fun test(foo: Any) {
async() { }
async() /**/ { }
foo async ({ })
async() { }
async({ })
foo async ({ })
foo async (fun () {})
foo async (fun () {})
async (fun () {})
async * {}
}

View File

@@ -0,0 +1,6 @@
// "Migrate unsupported async syntax" "true"
infix fun Any.async(f: () -> Unit) = f()
fun test(foo: Any) {
foo <caret>async { }
}

View File

@@ -0,0 +1,6 @@
// "Migrate unsupported async syntax" "true"
infix fun Any.async(f: () -> Unit) = f()
fun test(foo: Any) {
foo <caret>async ({ })
}

View File

@@ -0,0 +1,6 @@
// "Migrate unsupported async syntax" "true"
infix fun Any.async(f: () -> Unit) = f()
fun test(foo: Any) {
foo async<caret> fun () {}
}

View File

@@ -0,0 +1,6 @@
// "Migrate unsupported async syntax" "true"
infix fun Any.async(f: () -> Unit) = f()
fun test(foo: Any) {
foo async<caret> (fun () {})
}

View File

@@ -0,0 +1,6 @@
// "Migrate unsupported async syntax" "true"
fun async(f: () -> Unit) {}
fun test() {
asy<caret>nc { }
}

View File

@@ -0,0 +1,6 @@
// "Migrate unsupported async syntax" "true"
fun async(f: () -> Unit) {}
fun test() {
asy<caret>nc() { }
}

View File

@@ -0,0 +1,6 @@
// "Migrate unsupported async syntax" "true"
fun async(f: () -> Unit) {}
fun test() {
async<caret> /**/ { }
}

View File

@@ -0,0 +1,6 @@
// "Migrate unsupported async syntax" "true"
fun async(f: () -> Unit) {}
fun test() {
async<caret>() /**/ { }
}

View File

@@ -0,0 +1,8 @@
// "Migrate unsupported async syntax" "true"
object async {
operator fun times(f: () -> Unit) = f()
}
fun test() {
asy<caret>nc* { }
}

View File

@@ -0,0 +1,8 @@
// "Migrate unsupported async syntax" "true"
object async {
operator fun times(f: () -> Unit) = f()
}
fun test() {
asy<caret>nc * { }
}

View File

@@ -509,6 +509,45 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
}
}
@TestMetadata("idea/testData/quickfix/asyncUnsupported")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class AsyncUnsupported extends AbstractQuickFixTest {
public void testAllFilesPresentInAsyncUnsupported() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/asyncUnsupported"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
}
@TestMetadata("asyncInfixCall.kt")
public void testAsyncInfixCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/asyncUnsupported/asyncInfixCall.kt");
doTest(fileName);
}
@TestMetadata("asyncInfixCallWithFun.kt")
public void testAsyncInfixCallWithFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/asyncUnsupported/asyncInfixCallWithFun.kt");
doTest(fileName);
}
@TestMetadata("asyncWithLambda.kt")
public void testAsyncWithLambda() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/asyncUnsupported/asyncWithLambda.kt");
doTest(fileName);
}
@TestMetadata("asyncWithLambdaAndComment.kt")
public void testAsyncWithLambdaAndComment() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/asyncUnsupported/asyncWithLambdaAndComment.kt");
doTest(fileName);
}
@TestMetadata("asyncWithTimes.kt")
public void testAsyncWithTimes() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/asyncUnsupported/asyncWithTimes.kt");
doTest(fileName);
}
}
@TestMetadata("idea/testData/quickfix/autoImports")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -184,6 +184,12 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
messageCollector.report(INFO, "Kotlin JPS plugin version " + KotlinVersion.VERSION, CompilerMessageLocation.NO_LOCATION)
val targetsWithoutOutputDir = targets.filter { it.outputDir == null }
if (targetsWithoutOutputDir.isNotEmpty()) {
messageCollector.report(ERROR, "Output directory not specified for " + targetsWithoutOutputDir.joinToString(), CompilerMessageLocation.NO_LOCATION)
return ABORT
}
val project = projectDescriptor.project
val lookupTracker = getLookupTracker(project)
val incrementalCaches = getIncrementalCaches(chunk, context)

View File

@@ -115,12 +115,12 @@ public class KotlinBuilderModuleScriptGenerator {
}
@Nullable
public static File getFriendDirSafe(@NotNull ModuleBuildTarget target) throws ProjectBuildException {
private static File getFriendDirSafe(@NotNull ModuleBuildTarget target) throws ProjectBuildException {
if (!target.isTests()) return null;
File outputDirForProduction = JpsJavaExtensionService.getInstance().getOutputDirectory(target.getModule(), false);
if (outputDirForProduction == null) {
throw new ProjectBuildException("No output production directory found for " + target);
return null;
}
return outputDirForProduction;
}

View File

@@ -103,7 +103,7 @@ public class IncrementalCacheImpl(
private val supertypesMap = registerExperimentalMap(SupertypesMap(SUPERTYPES.storageFile))
private val dependents = arrayListOf<IncrementalCacheImpl>()
private val outputDir = requireNotNull(target.outputDir) { "Target is expected to have output directory: $target" }
private val outputDir by lazy(LazyThreadSafetyMode.NONE) { requireNotNull(target.outputDir) { "Target is expected to have output directory: $target" } }
private val dependentsWithThis: Iterable<IncrementalCacheImpl>
get() = dependents + this

View File

@@ -717,6 +717,25 @@ public class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
assertFalse(File(storageRoot, "targets/java-production/module2/kotlin").exists())
}
fun testKotlinProjectWithEmptyProductionOutputDir() {
initProject()
val result = makeAll()
result.assertFailed()
result.checkErrors()
}
fun testKotlinProjectWithEmptyTestOutputDir() {
doTest()
}
fun testKotlinProjectWithEmptyProductionOutputDirWithoutSrcDir() {
doTest()
}
fun testKotlinProjectWithEmptyOutputDirInSomeModules() {
doTest()
}
private fun BuildResult.checkErrors() {
val actualErrors = getMessages(BuildMessage.Kind.ERROR)
.map { it as CompilerMessage }

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
</component>
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/produciton_module/produciton_module.iml" filepath="$PROJECT_DIR$/produciton_module/produciton_module.iml" />
<module fileurl="file://$PROJECT_DIR$/test_module/test_module.iml" filepath="$PROJECT_DIR$/test_module/test_module.iml" />
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA_JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/../out/production/produciton_module" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="jdk" jdkName="IDEA_JDK" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,3 @@
fun test() {
foo()
}

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output-test url="file://$MODULE_DIR$/../out/test/test_module" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="jdk" jdkName="IDEA_JDK" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="produciton_module" />
</component>
</module>

View File

@@ -0,0 +1 @@
Output directory not specified for Module 'kotlinProject' production at line -1, column -1

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output-test url="file://$MODULE_DIR$/out/test/kotlinProject" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="jdk" jdkName="IDEA_JDK" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="kotlinProject" />
</component>
</module>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
</component>
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/kotlinProject.iml" filepath="$PROJECT_DIR$/kotlinProject.iml" />
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA_JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -0,0 +1,3 @@
fun foo() {
}

View File

@@ -0,0 +1,3 @@
fun test() {
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output-test url="file://$MODULE_DIR$/out/test/kotlinProject" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="jdk" jdkName="IDEA_JDK" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="kotlinProject" />
</component>
</module>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
</component>
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/kotlinProject.iml" filepath="$PROJECT_DIR$/kotlinProject.iml" />
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA_JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -0,0 +1,3 @@
fun test() {
}

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/out/production/kotlinProject" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
</content>
<orderEntry type="jdk" jdkName="IDEA_JDK" jdkType="JavaSDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="kotlinProject" />
</component>
</module>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
</component>
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/kotlinProject.iml" filepath="$PROJECT_DIR$/kotlinProject.iml" />
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA_JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@@ -0,0 +1,3 @@
fun foo() {
}

View File

@@ -0,0 +1,3 @@
fun test() {
}

View File

@@ -27,7 +27,7 @@
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin.test.junit</artifactId>
<artifactId>kotlin-test-junit</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

View File

@@ -22,7 +22,7 @@
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin.test.junit</artifactId>
<artifactId>kotlin-test-junit</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

View File

@@ -3,13 +3,13 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>kotlin.test.parent</artifactId>
<artifactId>kotlin-test-parent</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kotlin.test.js</artifactId>
<artifactId>kotlin-test-js</artifactId>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>kotlin.test.parent</artifactId>
<artifactId>kotlin-test-parent</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kotlin.test.junit</artifactId>
<artifactId>kotlin-test-junit</artifactId>
<dependencies>
<dependency>
@@ -18,7 +18,7 @@
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin.test</artifactId>
<artifactId>kotlin-test</artifactId>
<version>${project.version}</version>
<exclusions>

View File

@@ -8,7 +8,7 @@
<version>0.1-SNAPSHOT</version>
</parent>
<artifactId>kotlin.test.parent</artifactId>
<artifactId>kotlin-test-parent</artifactId>
<packaging>pom</packaging>
<modules>

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>kotlin.test.parent</artifactId>
<artifactId>kotlin-test-parent</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>kotlin.test</artifactId>
<artifactId>kotlin-test</artifactId>
<build>
<sourceDirectory>src/main/kotlin</sourceDirectory>
@@ -142,6 +142,15 @@
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>kotlin/internal/OnlyInputTypes*</exclude>
<exclude>kotlin/internal</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>

View File

@@ -21,7 +21,7 @@
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin.test.junit</artifactId>
<artifactId>kotlin-test-junit</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>

View File

@@ -12,6 +12,7 @@ public data class IndexedValue<out T>(public val index: Int, public val value: T
* A wrapper over another [Iterable] (or any other object that can produce an [Iterator]) that returns
* an indexing iterator.
*/
@Deprecated("This implementation class will become internal soon. Use Iterable<IndexedValue<T>> instead.", ReplaceWith("Iterable<IndexedValue<T>>"))
public class IndexingIterable<out T>(private val iteratorFactory: () -> Iterator<T>) : Iterable<IndexedValue<T>> {
override fun iterator(): Iterator<IndexedValue<T>> = IndexingIterator(iteratorFactory())
}
@@ -19,7 +20,10 @@ public class IndexingIterable<out T>(private val iteratorFactory: () -> Iterator
/**
* Iterator transforming original `iterator` into iterator of [IndexedValue], counting index from zero.
*/
public class IndexingIterator<out T>(private val iterator: Iterator<T>) : Iterator<IndexedValue<T>> {
@Deprecated("This implementation class will become internal soon. Use Iterator<IndexedValue<T>> instead.", ReplaceWith("Iterator<IndexedValue<T>>"))
public class IndexingIterator<out T>
@Deprecated("This implementation class will become internal soon. Use iterator.withIndex() instead.", ReplaceWith("iterator.withIndex()"))
constructor(private val iterator: Iterator<T>) : Iterator<IndexedValue<T>> {
private var index = 0
final override fun hasNext(): Boolean = iterator.hasNext()
final override fun next(): IndexedValue<T> = IndexedValue(index++, iterator.next())

View File

@@ -19,6 +19,12 @@ public operator fun <T> Enumeration<T>.iterator(): Iterator<T> = object : Iterat
*/
public operator fun <T> Iterator<T>.iterator(): Iterator<T> = this
/**
* Returns an [Iterator] wrapping each value produced by this [Iterator] with the [IndexedValue],
* containing value and it's index.
*/
public fun <T> Iterator<T>.withIndex(): Iterator<IndexedValue<T>> = IndexingIterator(this)
/**
* Performs the given [operation] on each element of this [Iterator].
*/

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