Cleanup: apply "cascade if..." inspection (+ some others)

This commit is contained in:
Mikhail Glukhikh
2017-06-28 15:19:20 +03:00
committed by Mikhail Glukhikh
parent 9c06739594
commit 1d2017b0fc
80 changed files with 1079 additions and 1190 deletions
@@ -292,14 +292,10 @@ fun calcTypeForIEEE754ArithmeticIfNeeded(expression: KtExpression?, bindingConte
val dataFlow = DataFlowValueFactory.createDataFlowValue(expression!!, ktType, bindingContext, descriptor) val dataFlow = DataFlowValueFactory.createDataFlowValue(expression!!, ktType, bindingContext, descriptor)
val stableTypes = bindingContext.getDataFlowInfoBefore(expression).getStableTypes(dataFlow) val stableTypes = bindingContext.getDataFlowInfoBefore(expression).getStableTypes(dataFlow)
return stableTypes.firstNotNullResult { return stableTypes.firstNotNullResult {
if (KotlinBuiltIns.isDoubleOrNullableDouble(it)) { when {
TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(it)) KotlinBuiltIns.isDoubleOrNullableDouble(it) -> TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(it))
} KotlinBuiltIns.isFloatOrNullableFloat(it) -> TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(it))
else if (KotlinBuiltIns.isFloatOrNullableFloat(it)) { else -> null
TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(it))
}
else {
null
} }
} }
} }
@@ -83,18 +83,16 @@ private fun ExpressionCodegen.createOptimizedForLoopGeneratorOrNull(
private fun getLoopRangeResolvedCall(forExpression: KtForExpression, bindingContext: BindingContext): ResolvedCall<out CallableDescriptor>? { private fun getLoopRangeResolvedCall(forExpression: KtForExpression, bindingContext: BindingContext): ResolvedCall<out CallableDescriptor>? {
val loopRange = KtPsiUtil.deparenthesize(forExpression.loopRange) val loopRange = KtPsiUtil.deparenthesize(forExpression.loopRange)
if (loopRange is KtQualifiedExpression) { when (loopRange) {
is KtQualifiedExpression -> {
val qualifiedExpression = loopRange as KtQualifiedExpression? val qualifiedExpression = loopRange as KtQualifiedExpression?
val selector = qualifiedExpression!!.selectorExpression val selector = qualifiedExpression!!.selectorExpression
if (selector is KtCallExpression || selector is KtSimpleNameExpression) { if (selector is KtCallExpression || selector is KtSimpleNameExpression) {
return selector.getResolvedCall(bindingContext) return selector.getResolvedCall(bindingContext)
} }
} }
else if (loopRange is KtSimpleNameExpression || loopRange is KtCallExpression) { is KtSimpleNameExpression, is KtCallExpression -> return loopRange.getResolvedCall(bindingContext)
return loopRange.getResolvedCall(bindingContext) is KtBinaryExpression -> return loopRange.operationReference.getResolvedCall(bindingContext)
}
else if (loopRange is KtBinaryExpression) {
return loopRange.operationReference.getResolvedCall(bindingContext)
} }
return null return null
@@ -610,14 +610,10 @@ class PsiInlineCodegen(
override fun putClosureParametersOnStack(next: LambdaInfo, functionReferenceReceiver: StackValue?) { override fun putClosureParametersOnStack(next: LambdaInfo, functionReferenceReceiver: StackValue?) {
activeLambda = next activeLambda = next
if (next is ExpressionLambda) { when (next) {
codegen.pushClosureOnStack(next.classDescriptor, true, this, functionReferenceReceiver) is ExpressionLambda -> codegen.pushClosureOnStack(next.classDescriptor, true, this, functionReferenceReceiver)
} is DefaultLambda -> rememberCapturedForDefaultLambda(next)
else if (next is DefaultLambda) { else -> throw RuntimeException("Unknown lambda: $next")
rememberCapturedForDefaultLambda(next)
}
else {
throw RuntimeException("Unknown lambda: $next")
} }
activeLambda = null activeLambda = null
} }
@@ -408,23 +408,27 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
sourceFile sourceFile
) )
if (descriptor is ScriptDescriptor) { return when (descriptor) {
is ScriptDescriptor -> {
val earlierScripts = state.replSpecific.earlierScriptsForReplInterpreter val earlierScripts = state.replSpecific.earlierScriptsForReplInterpreter
return parent.intoScript( parent.intoScript(
descriptor, descriptor,
earlierScripts ?: emptyList(), earlierScripts ?: emptyList(),
descriptor as ClassDescriptor, state.typeMapper descriptor as ClassDescriptor, state.typeMapper
) )
} }
else if (descriptor is ClassDescriptor) { is ClassDescriptor -> {
val kind = if (DescriptorUtils.isInterface(descriptor)) OwnerKind.DEFAULT_IMPLS else OwnerKind.IMPLEMENTATION val kind = if (DescriptorUtils.isInterface(descriptor)) OwnerKind.DEFAULT_IMPLS else OwnerKind.IMPLEMENTATION
return parent.intoClass(descriptor, kind, state) parent.intoClass(descriptor, kind, state)
} }
else if (descriptor is FunctionDescriptor) { is FunctionDescriptor -> {
return parent.intoFunction(descriptor) parent.intoFunction(descriptor)
} }
else -> {
throw IllegalStateException("Couldn't build context for " + descriptor) throw IllegalStateException("Couldn't build context for " + descriptor)
} }
} }
}
}
} }
@@ -171,7 +171,8 @@ private fun getInlineName(
typeMapper: KotlinTypeMapper, typeMapper: KotlinTypeMapper,
fileClassesProvider: JvmFileClassesProvider fileClassesProvider: JvmFileClassesProvider
): String { ): String {
if (currentDescriptor is PackageFragmentDescriptor) { when (currentDescriptor) {
is PackageFragmentDescriptor -> {
val file = DescriptorToSourceUtils.getContainingFile(codegenContext.contextDescriptor) val file = DescriptorToSourceUtils.getContainingFile(codegenContext.contextDescriptor)
val implementationOwnerType: Type? = val implementationOwnerType: Type? =
@@ -191,15 +192,16 @@ private fun getInlineName(
return implementationOwnerType.internalName return implementationOwnerType.internalName
} }
else if (currentDescriptor is ClassifierDescriptor) { is ClassifierDescriptor -> {
return typeMapper.mapType(currentDescriptor).internalName return typeMapper.mapType(currentDescriptor).internalName
} }
else if (currentDescriptor is FunctionDescriptor) { is FunctionDescriptor -> {
val descriptor = typeMapper.bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, currentDescriptor) val descriptor = typeMapper.bindingContext.get(CodegenBinding.CLASS_FOR_CALLABLE, currentDescriptor)
if (descriptor != null) { if (descriptor != null) {
return typeMapper.mapType(descriptor).internalName return typeMapper.mapType(descriptor).internalName
} }
} }
}
//TODO: add suffix for special case //TODO: add suffix for special case
val suffix = if (currentDescriptor.name.isSpecial) "" else currentDescriptor.name.asString() val suffix = if (currentDescriptor.name.isSpecial) "" else currentDescriptor.name.asString()
@@ -43,22 +43,24 @@ object JavaClassProperty : IntrinsicPropertyGetter() {
fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type { fun generateImpl(v: InstructionAdapter, receiver: StackValue): Type {
val type = receiver.type val type = receiver.type
if (type == Type.VOID_TYPE) { when {
type == Type.VOID_TYPE -> {
receiver.put(Type.VOID_TYPE, v) receiver.put(Type.VOID_TYPE, v)
StackValue.unit().put(UNIT_TYPE, v) StackValue.unit().put(UNIT_TYPE, v)
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false) v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
} }
else if (isPrimitive(type)) { isPrimitive(type) -> {
if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) { if (!StackValue.couldSkipReceiverOnStaticCall(receiver)) {
receiver.put(type, v) receiver.put(type, v)
AsmUtil.pop(v, type) AsmUtil.pop(v, type)
} }
v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;") v.getstatic(boxType(type).internalName, "TYPE", "Ljava/lang/Class;")
} }
else { else -> {
receiver.put(type, v) receiver.put(type, v)
v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false) v.invokevirtual("java/lang/Object", "getClass", "()Ljava/lang/Class;", false)
} }
}
return getType(Class::class.java) return getType(Class::class.java)
} }
@@ -1123,15 +1123,10 @@ class ControlFlowInformationProvider private constructor(
kind kind
} }
else { else {
if (check(kind, existingKind, IN_TRY, TAIL_CALL)) { when {
IN_TRY check(kind, existingKind, IN_TRY, TAIL_CALL) -> IN_TRY
} check(kind, existingKind, IN_TRY, NON_TAIL) -> IN_TRY
else if (check(kind, existingKind, IN_TRY, NON_TAIL)) { else -> NON_TAIL // TAIL_CALL, NON_TAIL
IN_TRY
}
else {
// TAIL_CALL, NON_TAIL
NON_TAIL
} }
} }
} }
@@ -107,17 +107,19 @@ class UnreachableCodeImpl(
currentTextRange, element -> currentTextRange, element ->
val elementRange = element.textRange!! val elementRange = element.textRange!!
if (currentTextRange == null) { when {
currentTextRange == null -> {
elementRange elementRange
} }
else if (currentTextRange.endOffset == elementRange.startOffset) { currentTextRange.endOffset == elementRange.startOffset -> {
currentTextRange.union(elementRange) currentTextRange.union(elementRange)
} }
else { else -> {
result.add(currentTextRange) result.add(currentTextRange)
elementRange elementRange
} }
} }
}
if (lastRange != null) { if (lastRange != null) {
result.add(lastRange) result.add(lastRange)
} }
@@ -47,4 +47,8 @@ class SyntheticFieldDescriptor private constructor(
} }
val DeclarationDescriptor.referencedProperty: PropertyDescriptor? val DeclarationDescriptor.referencedProperty: PropertyDescriptor?
get() = if (this is SyntheticFieldDescriptor) this.propertyDescriptor else if (this is PropertyDescriptor) this else null get() = when (this) {
is SyntheticFieldDescriptor -> this.propertyDescriptor
is PropertyDescriptor -> this
else -> null
}
@@ -458,7 +458,11 @@ object Renderers {
private fun renderTypeBounds(typeBounds: TypeBounds, short: Boolean): String { private fun renderTypeBounds(typeBounds: TypeBounds, short: Boolean): String {
val renderBound = { bound: Bound -> val renderBound = { bound: Bound ->
val arrow = if (bound.kind == LOWER_BOUND) ">: " else if (bound.kind == UPPER_BOUND) "<: " else ":= " val arrow = when (bound.kind) {
LOWER_BOUND -> ">: "
UPPER_BOUND -> "<: "
else -> ":= "
}
val renderer = if (short) DescriptorRenderer.SHORT_NAMES_IN_TYPES else DescriptorRenderer.FQ_NAMES_IN_TYPES val renderer = if (short) DescriptorRenderer.SHORT_NAMES_IN_TYPES else DescriptorRenderer.FQ_NAMES_IN_TYPES
val renderedBound = arrow + renderer.renderType(bound.constrainingType) + if (!bound.isProper) "*" else "" val renderedBound = arrow + renderer.renderType(bound.constrainingType) + if (!bound.isProper) "*" else ""
if (short) renderedBound else renderedBound + '(' + bound.position + ')' if (short) renderedBound else renderedBound + '(' + bound.position + ')'
@@ -202,32 +202,28 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
(descriptor as? ClassDescriptor)?.let { TargetList(KotlinTarget.classActualTargets(it)) } ?: TargetLists.T_CLASSIFIER (descriptor as? ClassDescriptor)?.let { TargetList(KotlinTarget.classActualTargets(it)) } ?: TargetLists.T_CLASSIFIER
is KtDestructuringDeclarationEntry -> TargetLists.T_LOCAL_VARIABLE is KtDestructuringDeclarationEntry -> TargetLists.T_LOCAL_VARIABLE
is KtProperty -> { is KtProperty -> {
if (annotated.isLocal) when {
TargetLists.T_LOCAL_VARIABLE annotated.isLocal -> TargetLists.T_LOCAL_VARIABLE
else if (annotated.isMember) annotated.isMember -> TargetLists.T_MEMBER_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
TargetLists.T_MEMBER_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate()) else -> TargetLists.T_TOP_LEVEL_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
else }
TargetLists.T_TOP_LEVEL_PROPERTY(descriptor.hasBackingField(trace), annotated.hasDelegate())
} }
is KtParameter -> { is KtParameter -> {
val destructuringDeclaration = annotated.destructuringDeclaration val destructuringDeclaration = annotated.destructuringDeclaration
if (destructuringDeclaration != null) when {
TargetLists.T_DESTRUCTURING_DECLARATION destructuringDeclaration != null -> TargetLists.T_DESTRUCTURING_DECLARATION
else if (annotated.hasValOrVar()) annotated.hasValOrVar() -> TargetLists.T_VALUE_PARAMETER_WITH_VAL
TargetLists.T_VALUE_PARAMETER_WITH_VAL else -> TargetLists.T_VALUE_PARAMETER_WITHOUT_VAL
else }
TargetLists.T_VALUE_PARAMETER_WITHOUT_VAL
} }
is KtConstructor<*> -> TargetLists.T_CONSTRUCTOR is KtConstructor<*> -> TargetLists.T_CONSTRUCTOR
is KtFunction -> { is KtFunction -> {
if (ExpressionTypingUtils.isFunctionExpression(descriptor)) when {
TargetLists.T_FUNCTION_EXPRESSION ExpressionTypingUtils.isFunctionExpression(descriptor) -> TargetLists.T_FUNCTION_EXPRESSION
else if (annotated.isLocal) annotated.isLocal -> TargetLists.T_LOCAL_FUNCTION
TargetLists.T_LOCAL_FUNCTION annotated.parent is KtClassOrObject || annotated.parent is KtClassBody -> TargetLists.T_MEMBER_FUNCTION
else if (annotated.parent is KtClassOrObject || annotated.parent is KtClassBody) else -> TargetLists.T_TOP_LEVEL_FUNCTION
TargetLists.T_MEMBER_FUNCTION }
else
TargetLists.T_TOP_LEVEL_FUNCTION
} }
is KtTypeAlias -> TargetLists.T_TYPEALIAS is KtTypeAlias -> TargetLists.T_TYPEALIAS
is KtPropertyAccessor -> if (annotated.isGetter) TargetLists.T_PROPERTY_GETTER else TargetLists.T_PROPERTY_SETTER is KtPropertyAccessor -> if (annotated.isGetter) TargetLists.T_PROPERTY_GETTER else TargetLists.T_PROPERTY_SETTER
@@ -266,18 +262,20 @@ class AnnotationChecker(private val additionalCheckers: Iterable<AdditionalAnnot
} }
fun T_MEMBER_PROPERTY(backingField: Boolean, delegate: Boolean) = fun T_MEMBER_PROPERTY(backingField: Boolean, delegate: Boolean) =
targetList(if (backingField) MEMBER_PROPERTY_WITH_BACKING_FIELD targetList(when {
else if (delegate) MEMBER_PROPERTY_WITH_DELEGATE backingField -> MEMBER_PROPERTY_WITH_BACKING_FIELD
else MEMBER_PROPERTY_WITHOUT_FIELD_OR_DELEGATE, delegate -> MEMBER_PROPERTY_WITH_DELEGATE
MEMBER_PROPERTY, PROPERTY) { else -> MEMBER_PROPERTY_WITHOUT_FIELD_OR_DELEGATE
}, MEMBER_PROPERTY, PROPERTY) {
propertyTargets(backingField, delegate) propertyTargets(backingField, delegate)
} }
fun T_TOP_LEVEL_PROPERTY(backingField: Boolean, delegate: Boolean) = fun T_TOP_LEVEL_PROPERTY(backingField: Boolean, delegate: Boolean) =
targetList(if (backingField) TOP_LEVEL_PROPERTY_WITH_BACKING_FIELD targetList(when {
else if (delegate) TOP_LEVEL_PROPERTY_WITH_DELEGATE backingField -> TOP_LEVEL_PROPERTY_WITH_BACKING_FIELD
else TOP_LEVEL_PROPERTY_WITHOUT_FIELD_OR_DELEGATE, delegate -> TOP_LEVEL_PROPERTY_WITH_DELEGATE
TOP_LEVEL_PROPERTY, PROPERTY) { else -> TOP_LEVEL_PROPERTY_WITHOUT_FIELD_OR_DELEGATE
}, TOP_LEVEL_PROPERTY, PROPERTY) {
propertyTargets(backingField, delegate) propertyTargets(backingField, delegate)
} }
@@ -418,19 +418,19 @@ class DeclarationsChecker(
FiniteBoundRestrictionChecker.check(aClass, classDescriptor, trace) FiniteBoundRestrictionChecker.check(aClass, classDescriptor, trace)
NonExpansiveInheritanceRestrictionChecker.check(aClass, classDescriptor, trace) NonExpansiveInheritanceRestrictionChecker.check(aClass, classDescriptor, trace)
if (aClass.isInterface()) { when {
aClass.isInterface() -> {
checkConstructorInInterface(aClass) checkConstructorInInterface(aClass)
checkMethodsOfAnyInInterface(classDescriptor) checkMethodsOfAnyInInterface(classDescriptor)
if (aClass.isLocal && classDescriptor.containingDeclaration !is ClassDescriptor) { if (aClass.isLocal && classDescriptor.containingDeclaration !is ClassDescriptor) {
trace.report(LOCAL_INTERFACE_NOT_ALLOWED.on(aClass, classDescriptor)) trace.report(LOCAL_INTERFACE_NOT_ALLOWED.on(aClass, classDescriptor))
} }
} }
else if (classDescriptor.kind == ClassKind.ANNOTATION_CLASS) { classDescriptor.kind == ClassKind.ANNOTATION_CLASS -> {
checkAnnotationClassWithBody(aClass) checkAnnotationClassWithBody(aClass)
checkValOnAnnotationParameter(aClass) checkValOnAnnotationParameter(aClass)
} }
else if (aClass is KtEnumEntry) { aClass is KtEnumEntry -> checkEnumEntry(aClass, classDescriptor)
checkEnumEntry(aClass, classDescriptor)
} }
} }
@@ -692,17 +692,11 @@ class DeclarationsChecker(
val delegate = property.delegate val delegate = property.delegate
val isHeader = propertyDescriptor.isHeader val isHeader = propertyDescriptor.isHeader
if (initializer != null) { if (initializer != null) {
if (inInterface) { when {
trace.report(PROPERTY_INITIALIZER_IN_INTERFACE.on(initializer)) inInterface -> trace.report(PROPERTY_INITIALIZER_IN_INTERFACE.on(initializer))
} isHeader -> trace.report(HEADER_PROPERTY_INITIALIZER.on(initializer))
else if (isHeader) { !backingFieldRequired -> trace.report(PROPERTY_INITIALIZER_NO_BACKING_FIELD.on(initializer))
trace.report(HEADER_PROPERTY_INITIALIZER.on(initializer)) property.receiverTypeReference != null -> trace.report(EXTENSION_PROPERTY_WITH_BACKING_FIELD.on(initializer))
}
else if (!backingFieldRequired) {
trace.report(PROPERTY_INITIALIZER_NO_BACKING_FIELD.on(initializer))
}
else if (property.receiverTypeReference != null) {
trace.report(EXTENSION_PROPERTY_WITH_BACKING_FIELD.on(initializer))
} }
} }
else if (delegate != null) { else if (delegate != null) {
@@ -69,12 +69,11 @@ open class DelegatingBindingTrace(
private val bindingContext = MyBindingContext() private val bindingContext = MyBindingContext()
init { init {
this.mutableDiagnostics = if (filter.ignoreDiagnostics) this.mutableDiagnostics = when {
null filter.ignoreDiagnostics -> null
else if (withParentDiagnostics) withParentDiagnostics -> MutableDiagnosticsWithSuppression(bindingContext, parentContext.diagnostics)
MutableDiagnosticsWithSuppression(bindingContext, parentContext.diagnostics) else -> MutableDiagnosticsWithSuppression(bindingContext)
else }
MutableDiagnosticsWithSuppression(bindingContext)
} }
constructor(parentContext: BindingContext, constructor(parentContext: BindingContext,
@@ -122,13 +122,12 @@ class FunctionDescriptorResolver(
assert(function.typeReference == null) { assert(function.typeReference == null) {
"Return type must be initialized early for function: " + function.text + ", at: " + DiagnosticUtils.atLocation(function) } "Return type must be initialized early for function: " + function.text + ", at: " + DiagnosticUtils.atLocation(function) }
val returnType = if (function.hasBlockBody()) { val returnType = when {
function.hasBlockBody() ->
builtIns.unitType builtIns.unitType
} function.hasBody() ->
else if (function.hasBody()) {
descriptorResolver.inferReturnTypeFromExpressionBody(trace, scope, dataFlowInfo, function, functionDescriptor) descriptorResolver.inferReturnTypeFromExpressionBody(trace, scope, dataFlowInfo, function, functionDescriptor)
} else ->
else {
ErrorUtils.createErrorType("No type, no body") ErrorUtils.createErrorType("No type, no body")
} }
functionDescriptor.setReturnType(returnType) functionDescriptor.setReturnType(returnType)
@@ -340,14 +340,10 @@ object ModifierCheckerCore {
checkCompatibility(trace, first, second, list.owner, incorrectNodes) checkCompatibility(trace, first, second, list.owner, incorrectNodes)
} }
if (second !in incorrectNodes) { if (second !in incorrectNodes) {
if (!checkTarget(trace, second, actualTargets)) { when {
incorrectNodes += second !checkTarget(trace, second, actualTargets) -> incorrectNodes += second
} !checkParent(trace, second, parentDescriptor) -> incorrectNodes += second
else if (!checkParent(trace, second, parentDescriptor)) { !checkLanguageLevelSupport(trace, second, languageVersionSettings, actualTargets) -> incorrectNodes += second
incorrectNodes += second
}
else if (!checkLanguageLevelSupport(trace, second, languageVersionSettings, actualTargets)) {
incorrectNodes += second
} }
} }
} }
@@ -568,17 +568,19 @@ class QualifiedExpressionResolver {
) { ) {
if (descriptors.size > 1) { if (descriptors.size > 1) {
val visibleDescriptors = descriptors.filter { isVisible(it, shouldBeVisibleFrom, position) } val visibleDescriptors = descriptors.filter { isVisible(it, shouldBeVisibleFrom, position) }
if (visibleDescriptors.isEmpty()) { when {
visibleDescriptors.isEmpty() -> {
val descriptor = descriptors.first() as DeclarationDescriptorWithVisibility val descriptor = descriptors.first() as DeclarationDescriptorWithVisibility
trace.report(Errors.INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.visibility, descriptor)) trace.report(Errors.INVISIBLE_REFERENCE.on(referenceExpression, descriptor, descriptor.visibility, descriptor))
} }
else if (visibleDescriptors.size > 1) { visibleDescriptors.size > 1 -> {
trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, visibleDescriptors) trace.record(BindingContext.AMBIGUOUS_REFERENCE_TARGET, referenceExpression, visibleDescriptors)
} }
else { else -> {
storeResult(trace, referenceExpression, visibleDescriptors.single(), null, position, isQualifier) storeResult(trace, referenceExpression, visibleDescriptors.single(), null, position, isQualifier)
} }
} }
}
else { else {
storeResult(trace, referenceExpression, descriptors.singleOrNull(), shouldBeVisibleFrom, position, isQualifier) storeResult(trace, referenceExpression, descriptors.singleOrNull(), shouldBeVisibleFrom, position, isQualifier)
} }
@@ -155,11 +155,12 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
val varDescriptor: CallableDescriptor? val varDescriptor: CallableDescriptor?
val receiverExpression: KtExpression? val receiverExpression: KtExpression?
if (receiver is ExpressionReceiver) { when (receiver) {
is ExpressionReceiver -> {
receiverExpression = receiver.expression receiverExpression = receiver.expression
varDescriptor = getCalleeDescriptor(context, receiverExpression, true) varDescriptor = getCalleeDescriptor(context, receiverExpression, true)
} }
else if (receiver is ExtensionReceiver) { is ExtensionReceiver -> {
val extension = receiver.declarationDescriptor val extension = receiver.declarationDescriptor
varDescriptor = extension.extensionReceiverParameter varDescriptor = extension.extensionReceiverParameter
@@ -167,10 +168,11 @@ internal class InlineChecker(private val descriptor: FunctionDescriptor) : CallC
receiverExpression = expression receiverExpression = expression
} }
else { else -> {
varDescriptor = null varDescriptor = null
receiverExpression = null receiverExpression = null
} }
}
if (inlinableParameters.contains(varDescriptor)) { if (inlinableParameters.contains(varDescriptor)) {
//check that it's invoke or inlinable extension //check that it's invoke or inlinable extension
@@ -50,20 +50,20 @@ fun ResolvedCall<*>.hasThisOrNoDispatchReceiver(
if (resultingDescriptor.dispatchReceiverParameter == null || dispatchReceiverValue == null) return true if (resultingDescriptor.dispatchReceiverParameter == null || dispatchReceiverValue == null) return true
var dispatchReceiverDescriptor: DeclarationDescriptor? = null var dispatchReceiverDescriptor: DeclarationDescriptor? = null
if (dispatchReceiverValue is ImplicitReceiver) { when (dispatchReceiverValue) {
// foo() -- implicit receiver is ImplicitReceiver -> // foo() -- implicit receiver
dispatchReceiverDescriptor = dispatchReceiverValue.declarationDescriptor dispatchReceiverDescriptor = dispatchReceiverValue.declarationDescriptor
} is ClassValueReceiver -> {
else if (dispatchReceiverValue is ClassValueReceiver) {
dispatchReceiverDescriptor = dispatchReceiverValue.classQualifier.descriptor dispatchReceiverDescriptor = dispatchReceiverValue.classQualifier.descriptor
} }
else if (dispatchReceiverValue is ExpressionReceiver) { is ExpressionReceiver -> {
val expression = KtPsiUtil.deparenthesize(dispatchReceiverValue.expression) val expression = KtPsiUtil.deparenthesize(dispatchReceiverValue.expression)
if (expression is KtThisExpression) { if (expression is KtThisExpression) {
// this.foo() -- explicit receiver // this.foo() -- explicit receiver
dispatchReceiverDescriptor = context.get(BindingContext.REFERENCE_TARGET, expression.instanceReference) dispatchReceiverDescriptor = context.get(BindingContext.REFERENCE_TARGET, expression.instanceReference)
} }
} }
}
return dispatchReceiverDescriptor == resultingDescriptor.getOwnerForEffectiveDispatchReceiverParameter() return dispatchReceiverDescriptor == resultingDescriptor.getOwnerForEffectiveDispatchReceiverParameter()
} }
@@ -283,9 +283,11 @@ internal class DelegatingDataFlowInfo private constructor(
private fun Set<KotlinType>.containsNothing() = any { KotlinBuiltIns.isNothing(it) } private fun Set<KotlinType>.containsNothing() = any { KotlinBuiltIns.isNothing(it) }
private fun Set<KotlinType>.intersect(other: Set<KotlinType>) = private fun Set<KotlinType>.intersect(other: Set<KotlinType>) =
if (other.containsNothing()) this when {
else if (this.containsNothing()) other other.containsNothing() -> this
else Sets.intersection(this, other) this.containsNothing() -> other
else -> Sets.intersection(this, other)
}
override fun or(other: DataFlowInfo): DataFlowInfo { override fun or(other: DataFlowInfo): DataFlowInfo {
if (other === DataFlowInfo.EMPTY) return DataFlowInfo.EMPTY if (other === DataFlowInfo.EMPTY) return DataFlowInfo.EMPTY
@@ -145,14 +145,10 @@ abstract class KotlinSuppressCache {
var suppressor: Suppressor? = suppressors[annotated] var suppressor: Suppressor? = suppressors[annotated]
if (suppressor == null) { if (suppressor == null) {
val strings = getSuppressingStrings(annotated) val strings = getSuppressingStrings(annotated)
if (strings.isEmpty()) { suppressor = when {
suppressor = EmptySuppressor(annotated) strings.isEmpty() -> EmptySuppressor(annotated)
} strings.size == 1 -> SingularSuppressor(annotated, strings.iterator().next())
else if (strings.size == 1) { else -> MultiSuppressor(annotated, strings)
suppressor = SingularSuppressor(annotated, strings.iterator().next())
}
else {
suppressor = MultiSuppressor(annotated, strings)
} }
suppressors.put(annotated, suppressor) suppressors.put(annotated, suppressor)
} }
@@ -169,46 +169,48 @@ protected constructor(
val declarations = declarationProvider.getDeclarations(kindFilter, nameFilter) val declarations = declarationProvider.getDeclarations(kindFilter, nameFilter)
val result = LinkedHashSet<DeclarationDescriptor>(declarations.size) val result = LinkedHashSet<DeclarationDescriptor>(declarations.size)
for (declaration in declarations) { for (declaration in declarations) {
if (declaration is KtClassOrObject) { when (declaration) {
is KtClassOrObject -> {
val name = declaration.nameAsSafeName val name = declaration.nameAsSafeName
if (nameFilter(name)) { if (nameFilter(name)) {
result.addAll(classDescriptors(name)) result.addAll(classDescriptors(name))
} }
} }
else if (declaration is KtFunction) { is KtFunction -> {
val name = declaration.nameAsSafeName val name = declaration.nameAsSafeName
if (nameFilter(name)) { if (nameFilter(name)) {
result.addAll(getContributedFunctions(name, location)) result.addAll(getContributedFunctions(name, location))
} }
} }
else if (declaration is KtProperty) { is KtProperty -> {
val name = declaration.nameAsSafeName val name = declaration.nameAsSafeName
if (nameFilter(name)) { if (nameFilter(name)) {
result.addAll(getContributedVariables(name, location)) result.addAll(getContributedVariables(name, location))
} }
} }
else if (declaration is KtParameter) { is KtParameter -> {
val name = declaration.nameAsSafeName val name = declaration.nameAsSafeName
if (nameFilter(name)) { if (nameFilter(name)) {
result.addAll(getContributedVariables(name, location)) result.addAll(getContributedVariables(name, location))
} }
} }
else if (declaration is KtTypeAlias) { is KtTypeAlias -> {
val name = declaration.nameAsSafeName val name = declaration.nameAsSafeName
if (nameFilter(name)) { if (nameFilter(name)) {
result.addAll(getContributedTypeAliasDescriptors(name, location)) result.addAll(getContributedTypeAliasDescriptors(name, location))
} }
} }
else if (declaration is KtScript) { is KtScript -> {
val name = declaration.nameAsSafeName val name = declaration.nameAsSafeName
if (nameFilter(name)) { if (nameFilter(name)) {
result.addAll(classDescriptors(name)) result.addAll(classDescriptors(name))
} }
} }
else if (declaration is KtDestructuringDeclaration) { is KtDestructuringDeclaration -> {
// MultiDeclarations are not supported on global level // MultiDeclarations are not supported on global level
} }
else throw IllegalArgumentException("Unsupported declaration kind: " + declaration) else -> throw IllegalArgumentException("Unsupported declaration kind: " + declaration)
}
} }
return result.toList() return result.toList()
} }
@@ -137,7 +137,8 @@ object LabelResolver {
val declarationsByLabel = context.scope.getDeclarationsByLabel(labelName) val declarationsByLabel = context.scope.getDeclarationsByLabel(labelName)
val size = declarationsByLabel.size val size = declarationsByLabel.size
if (size == 1) { when (size) {
1 -> {
val declarationDescriptor = declarationsByLabel.single() val declarationDescriptor = declarationsByLabel.single()
val thisReceiver = when (declarationDescriptor) { val thisReceiver = when (declarationDescriptor) {
is ClassDescriptor -> declarationDescriptor.thisAsReceiverParameter is ClassDescriptor -> declarationDescriptor.thisAsReceiverParameter
@@ -146,7 +147,8 @@ object LabelResolver {
else -> throw UnsupportedOperationException("Unsupported descriptor: " + declarationDescriptor) // TODO else -> throw UnsupportedOperationException("Unsupported descriptor: " + declarationDescriptor) // TODO
} }
val element = DescriptorToSourceUtils.descriptorToDeclaration(declarationDescriptor) ?: error("No PSI element for descriptor: " + declarationDescriptor) val element = DescriptorToSourceUtils.descriptorToDeclaration(declarationDescriptor)
?: error("No PSI element for descriptor: " + declarationDescriptor)
context.trace.record(LABEL_TARGET, targetLabel, element) context.trace.record(LABEL_TARGET, targetLabel, element)
context.trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor) context.trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
@@ -158,7 +160,7 @@ object LabelResolver {
return LabeledReceiverResolutionResult.labelResolutionSuccess(thisReceiver) return LabeledReceiverResolutionResult.labelResolutionSuccess(thisReceiver)
} }
else if (size == 0) { 0 -> {
val element = resolveNamedLabel(labelName, targetLabel, context.trace) val element = resolveNamedLabel(labelName, targetLabel, context.trace)
val declarationDescriptor = context.trace.bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, element] val declarationDescriptor = context.trace.bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, element]
if (declarationDescriptor is FunctionDescriptor) { if (declarationDescriptor is FunctionDescriptor) {
@@ -173,8 +175,7 @@ object LabelResolver {
context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel, targetLabel)) context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel, targetLabel))
} }
} }
else { else -> BindingContextUtils.reportAmbiguousLabel(context.trace, targetLabel, declarationsByLabel)
BindingContextUtils.reportAmbiguousLabel(context.trace, targetLabel, declarationsByLabel)
} }
return LabeledReceiverResolutionResult.labelResolutionFailed() return LabeledReceiverResolutionResult.labelResolutionFailed()
} }
@@ -38,9 +38,11 @@ object SenselessComparisonChecker {
getNullability: (DataFlowValue) -> Nullability getNullability: (DataFlowValue) -> Nullability
) { ) {
val expr = val expr =
if (KtPsiUtil.isNullConstant(left)) right when {
else if (KtPsiUtil.isNullConstant(right)) left KtPsiUtil.isNullConstant(left) -> right
else return KtPsiUtil.isNullConstant(right) -> left
else -> return
}
val type = getType(expr) val type = getType(expr)
if (type == null || type.isError) return if (type == null || type.isError) return
@@ -52,10 +54,12 @@ object SenselessComparisonChecker {
val nullability = getNullability(value) val nullability = getNullability(value)
val expressionIsAlways = val expressionIsAlways =
if (nullability == Nullability.NULL) equality when (nullability) {
else if (nullability == Nullability.NOT_NULL) !equality Nullability.NULL -> equality
else if (nullability == Nullability.IMPOSSIBLE) false Nullability.NOT_NULL -> !equality
else return Nullability.IMPOSSIBLE -> false
else -> return
}
context.trace.report(Errors.SENSELESS_COMPARISON.on(expression, expression, expressionIsAlways)) context.trace.report(Errors.SENSELESS_COMPARISON.on(expression, expression, expressionIsAlways))
} }
@@ -632,11 +632,10 @@ class ExpressionCodegen(
val stackElement = data.peek() val stackElement = data.peek()
if (stackElement is TryInfo) { when (stackElement) {
//noinspection ConstantConditions is TryInfo -> //noinspection ConstantConditions
genFinallyBlockOrGoto(stackElement, null, afterBreakContinueLabel, data) genFinallyBlockOrGoto(stackElement, null, afterBreakContinueLabel, data)
} is LoopInfo -> {
else if (stackElement is LoopInfo) {
val loop = expression.loop val loop = expression.loop
//noinspection ConstantConditions //noinspection ConstantConditions
if (loop == stackElement.loop) { if (loop == stackElement.loop) {
@@ -646,8 +645,7 @@ class ExpressionCodegen(
return return
} }
} }
else { else -> throw UnsupportedOperationException("Wrong BlockStackElement in processing stack")
throw UnsupportedOperationException("Wrong BlockStackElement in processing stack")
} }
data.pop() data.pop()
@@ -829,14 +827,12 @@ class ExpressionCodegen(
private fun doFinallyOnReturn(afterReturnLabel: Label, data: BlockInfo) { private fun doFinallyOnReturn(afterReturnLabel: Label, data: BlockInfo) {
if (!data.isEmpty()) { if (!data.isEmpty()) {
val stackElement = data.peek() val stackElement = data.peek()
if (stackElement is TryInfo) { when (stackElement) {
genFinallyBlockOrGoto(stackElement, null, afterReturnLabel, data) is TryInfo -> genFinallyBlockOrGoto(stackElement, null, afterReturnLabel, data)
} is LoopInfo -> {
else if (stackElement is LoopInfo) {
} }
else { else -> throw UnsupportedOperationException("Wrong BlockStackElement in processing stack")
throw UnsupportedOperationException("Wrong BlockStackElement in processing stack")
} }
data.pop() data.pop()
@@ -163,18 +163,20 @@ class StatementGenerator(
} }
else { else {
val label = expression.getTargetLabel() val label = expression.getTargetLabel()
if (label != null) { when {
label != null -> {
val labelTarget = getOrFail(BindingContext.LABEL_TARGET, label) val labelTarget = getOrFail(BindingContext.LABEL_TARGET, label)
val labelTargetDescriptor = getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, labelTarget) val labelTargetDescriptor = getOrFail(BindingContext.DECLARATION_TO_DESCRIPTOR, labelTarget)
labelTargetDescriptor as CallableDescriptor labelTargetDescriptor as CallableDescriptor
} }
else if (ExpressionTypingUtils.isFunctionLiteral(scopeOwner)) { ExpressionTypingUtils.isFunctionLiteral(scopeOwner) -> {
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(scopeOwner, true).first BindingContextUtils.getContainingFunctionSkipFunctionLiterals(scopeOwner, true).first
} }
else { else -> {
scopeOwnerAsCallable() scopeOwnerAsCallable()
} }
} }
}
override fun visitThrowExpression(expression: KtThrowExpression, data: Nothing?): IrStatement { override fun visitThrowExpression(expression: KtThrowExpression, data: Nothing?): IrStatement {
return IrThrowImpl(expression.startOffset, expression.endOffset, context.builtIns.nothingType, expression.thrownExpression!!.genExpr()) return IrThrowImpl(expression.startOffset, expression.endOffset, context.builtIns.nothingType, expression.thrownExpression!!.genExpr())
@@ -168,25 +168,27 @@ private fun <C : Candidate> createSimpleProcessor(
classValueReceiver: Boolean, classValueReceiver: Boolean,
collectCandidates: CandidatesCollector collectCandidates: CandidatesCollector
) : ScopeTowerProcessor<C> { ) : ScopeTowerProcessor<C> {
if (explicitReceiver is ReceiverValueWithSmartCastInfo) { return when (explicitReceiver) {
return ExplicitReceiverScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) is ReceiverValueWithSmartCastInfo -> {
ExplicitReceiverScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates)
} }
else if (explicitReceiver is QualifierReceiver) { is QualifierReceiver -> {
val qualifierProcessor = QualifierScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates) val qualifierProcessor = QualifierScopeTowerProcessor(scopeTower, context, explicitReceiver, collectCandidates)
if (!classValueReceiver) return qualifierProcessor if (!classValueReceiver) return qualifierProcessor
// todo enum entry, object. // todo enum entry, object.
val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return qualifierProcessor val classValue = explicitReceiver.classValueReceiverWithSmartCastInfo ?: return qualifierProcessor
return CompositeScopeTowerProcessor( CompositeScopeTowerProcessor(
qualifierProcessor, qualifierProcessor,
ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates) ExplicitReceiverScopeTowerProcessor(scopeTower, context, classValue, collectCandidates)
) )
} }
else { else -> {
assert(explicitReceiver == null) { assert(explicitReceiver == null) {
"Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!::class.java.simpleName})" "Illegal explicit receiver: $explicitReceiver(${explicitReceiver!!::class.java.simpleName})"
} }
return NoExplicitReceiverScopeTowerProcessor(context, collectCandidates) NoExplicitReceiverScopeTowerProcessor(context, collectCandidates)
}
} }
} }
@@ -252,7 +252,8 @@ object NewKotlinTypeChecker : KotlinTypeChecker {
anySupertype(baseType, { false }) { anySupertype(baseType, { false }) {
val current = captureFromArguments(it, CaptureStatus.FOR_SUBTYPING) val current = captureFromArguments(it, CaptureStatus.FOR_SUBTYPING)
if (areEqualTypeConstructors(current.constructor, constructor)) { when {
areEqualTypeConstructors(current.constructor, constructor) -> {
if (result == null) { if (result == null) {
result = SmartList() result = SmartList()
} }
@@ -260,13 +261,14 @@ object NewKotlinTypeChecker : KotlinTypeChecker {
SupertypesPolicy.None SupertypesPolicy.None
} }
else if (current.arguments.isEmpty()) { current.arguments.isEmpty() -> {
SupertypesPolicy.LowerIfFlexible SupertypesPolicy.LowerIfFlexible
} }
else { else -> {
SupertypesPolicy.LowerIfFlexibleWithCustomSubstitutor(TypeConstructorSubstitution.create(current).buildSubstitutor()) SupertypesPolicy.LowerIfFlexibleWithCustomSubstitutor(TypeConstructorSubstitution.create(current).buildSubstitutor())
} }
} }
}
return result ?: emptyList() return result ?: emptyList()
} }
@@ -208,29 +208,33 @@ internal object RuntimeTypeMapper {
fun mapPropertySignature(possiblyOverriddenProperty: PropertyDescriptor): JvmPropertySignature { fun mapPropertySignature(possiblyOverriddenProperty: PropertyDescriptor): JvmPropertySignature {
val property = DescriptorUtils.unwrapFakeOverride(possiblyOverriddenProperty).original val property = DescriptorUtils.unwrapFakeOverride(possiblyOverriddenProperty).original
if (property is DeserializedPropertyDescriptor) { return when (property) {
is DeserializedPropertyDescriptor -> {
val proto = property.proto val proto = property.proto
if (!proto.hasExtension(JvmProtoBuf.propertySignature)) { if (!proto.hasExtension(JvmProtoBuf.propertySignature)) {
// If this property has no JVM signature, it must be from built-ins // If this property has no JVM signature, it must be from built-ins
throw KotlinReflectionInternalError("Reflection on built-in Kotlin types is not yet fully supported. " + throw KotlinReflectionInternalError("Reflection on built-in Kotlin types is not yet fully supported. " +
"No metadata found for $property") "No metadata found for $property")
} }
return JvmPropertySignature.KotlinProperty( JvmPropertySignature.KotlinProperty(
property, proto, proto.getExtension(JvmProtoBuf.propertySignature), property.nameResolver, property.typeTable property, proto, proto.getExtension(JvmProtoBuf.propertySignature), property.nameResolver, property.typeTable
) )
} }
else if (property is JavaPropertyDescriptor) { is JavaPropertyDescriptor -> {
val element = (property.source as? JavaSourceElement)?.javaElement val element = (property.source as? JavaSourceElement)?.javaElement
when (element) { when (element) {
is ReflectJavaField -> return JvmPropertySignature.JavaField(element.member) is ReflectJavaField -> JvmPropertySignature.JavaField(element.member)
is ReflectJavaMethod -> return JvmPropertySignature.JavaMethodProperty( is ReflectJavaMethod -> JvmPropertySignature.JavaMethodProperty(
element.member, element.member,
((property.setter?.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member ((property.setter?.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member
) )
else -> throw KotlinReflectionInternalError("Incorrect resolution sequence for Java field $property (source = $element)") else -> throw KotlinReflectionInternalError("Incorrect resolution sequence for Java field $property (source = $element)")
} }
} }
else throw KotlinReflectionInternalError("Unknown origin of $property (${property.javaClass})") else -> {
throw KotlinReflectionInternalError("Unknown origin of $property (${property.javaClass})")
}
}
} }
private fun mapIntrinsicFunctionSignature(function: FunctionDescriptor): JvmFunctionSignature? { private fun mapIntrinsicFunctionSignature(function: FunctionDescriptor): JvmFunctionSignature? {
@@ -181,13 +181,10 @@ class SingleInstructionInterpreter(private val eval: Eval) : Interpreter<Value>(
CHECKCAST -> { CHECKCAST -> {
val targetType = Type.getObjectType((insn as TypeInsnNode).desc) val targetType = Type.getObjectType((insn as TypeInsnNode).desc)
if (value == NULL_VALUE) { when {
NULL_VALUE value == NULL_VALUE -> NULL_VALUE
} else if (eval.isInstanceOf(value, targetType)) { eval.isInstanceOf(value, targetType) -> ObjectValue(value.obj(), targetType)
ObjectValue(value.obj(), targetType) else -> throwEvalException(ClassCastException("${value.asmType.className} cannot be cast to ${targetType.className}"))
}
else {
throwEvalException(ClassCastException("${value.asmType.className} cannot be cast to ${targetType.className}"))
} }
} }
@@ -212,13 +212,12 @@ class OptimizedImportsBuilder(
val explicitImportPath = ImportPath(fqName, false) val explicitImportPath = ImportPath(fqName, false)
val starImportPath = ImportPath(fqName.parent(), true) val starImportPath = ImportPath(fqName.parent(), true)
val importPaths = file.importDirectives.map { it.importPath } val importPaths = file.importDirectives.map { it.importPath }
if (explicitImportPath in importPaths) { when {
explicitImportPath in importPaths ->
importRules.add(ImportRule.Add(explicitImportPath)) importRules.add(ImportRule.Add(explicitImportPath))
} starImportPath in importPaths ->
else if (starImportPath in importPaths) {
importRules.add(ImportRule.Add(starImportPath)) importRules.add(ImportRule.Add(starImportPath))
} else -> // there is no import for this descriptor in the original import list, so do not allow to import it by star-import
else { // there is no import for this descriptor in the original import list, so do not allow to import it by star-import
importRules.add(ImportRule.DoNotAdd(starImportPath)) importRules.add(ImportRule.DoNotAdd(starImportPath))
} }
} }
@@ -277,14 +276,10 @@ class OptimizedImportsBuilder(
val iterator1 = tower1.iterator() val iterator1 = tower1.iterator()
val iterator2 = tower2.iterator() val iterator2 = tower2.iterator()
while (true) { while (true) {
if (!iterator1.hasNext()) { when {
return !iterator2.hasNext() !iterator1.hasNext() -> return !iterator2.hasNext()
} !iterator2.hasNext() -> return false
else if (!iterator2.hasNext()) { else -> if (!areTargetsEqual(iterator1.next(), iterator2.next())) return false
return false
}
else {
if (!areTargetsEqual(iterator1.next(), iterator2.next())) return false
} }
} }
} }
@@ -271,18 +271,18 @@ class PartialBodyResolveFilter(
val left = condition.left ?: return emptyResult val left = condition.left ?: return emptyResult
val right = condition.right ?: return emptyResult val right = condition.right ?: return emptyResult
fun smartCastInEq(): Pair<Set<SmartCastName>, Set<SmartCastName>> { fun smartCastInEq(): Pair<Set<SmartCastName>, Set<SmartCastName>> = when {
if (left.isNullLiteral()) { left.isNullLiteral() -> {
return Pair(setOf(), right.smartCastExpressionName().singletonOrEmptySet()) Pair(setOf(), right.smartCastExpressionName().singletonOrEmptySet())
} }
else if (right.isNullLiteral()) { right.isNullLiteral() -> {
return Pair(setOf(), left.smartCastExpressionName().singletonOrEmptySet()) Pair(setOf(), left.smartCastExpressionName().singletonOrEmptySet())
} }
else { else -> {
val leftName = left.smartCastExpressionName() val leftName = left.smartCastExpressionName()
val rightName = right.smartCastExpressionName() val rightName = right.smartCastExpressionName()
val names = listOfNotNull(leftName, rightName).toSet() val names = listOfNotNull(leftName, rightName).toSet()
return Pair(names, setOf()) Pair(names, setOf())
} }
} }
@@ -217,26 +217,26 @@ object IDELightClassContexts {
} }
for (declaration in file.declarations) { for (declaration in file.declarations) {
if (declaration is KtFunction) { when (declaration) {
is KtFunction -> {
val name = declaration.nameAsSafeName val name = declaration.nameAsSafeName
val functions = packageDescriptor.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_IDE) val functions = packageDescriptor.memberScope.getContributedFunctions(name, NoLookupLocation.FROM_IDE)
for (descriptor in functions) { for (descriptor in functions) {
ForceResolveUtil.forceResolveAllContents(descriptor) ForceResolveUtil.forceResolveAllContents(descriptor)
} }
} }
else if (declaration is KtProperty) { is KtProperty -> {
val name = declaration.nameAsSafeName val name = declaration.nameAsSafeName
val properties = packageDescriptor.memberScope.getContributedVariables(name, NoLookupLocation.FROM_IDE) val properties = packageDescriptor.memberScope.getContributedVariables(name, NoLookupLocation.FROM_IDE)
for (descriptor in properties) { for (descriptor in properties) {
ForceResolveUtil.forceResolveAllContents(descriptor) ForceResolveUtil.forceResolveAllContents(descriptor)
} }
} }
else if (declaration is KtClassOrObject || declaration is KtTypeAlias || declaration is KtDestructuringDeclaration) { is KtClassOrObject, is KtTypeAlias, is KtDestructuringDeclaration -> {
// Do nothing: we are not interested in classes or type aliases, // Do nothing: we are not interested in classes or type aliases,
// and all destructuring declarations are erroneous at top level // and all destructuring declarations are erroneous at top level
} }
else { else -> LOG.error("Unsupported declaration kind: " + declaration + " in file " + file.name + "\n" + file.text)
LOG.error("Unsupported declaration kind: " + declaration + " in file " + file.name + "\n" + file.text)
} }
} }
@@ -101,11 +101,18 @@ object UsageTypeUtils {
CLASS_CAST_TO CLASS_CAST_TO
with(refExpr.getNonStrictParentOfType<KtDotQualifiedExpression>()) { with(refExpr.getNonStrictParentOfType<KtDotQualifiedExpression>()) {
if (this == null) false when {
else if (receiverExpression == refExpr) true this == null -> {
else false
}
receiverExpression == refExpr -> {
true
}
else -> {
selectorExpression == refExpr selectorExpression == refExpr
&& getParentOfTypeAndBranch<KtDotQualifiedExpression>(strict = true) { receiverExpression } != null && getParentOfTypeAndBranch<KtDotQualifiedExpression>(strict = true) { receiverExpression } != null
}
}
} -> } ->
CLASS_OBJECT_ACCESS CLASS_OBJECT_ACCESS
@@ -49,12 +49,11 @@ object CommonLibraryDetectionUtil {
var platform: TargetPlatform? = null var platform: TargetPlatform? = null
VfsUtilCore.processFilesRecursively(root) { file -> VfsUtilCore.processFilesRecursively(root) { file ->
if (file.fileType == JavaClassFileType.INSTANCE) when {
platform = JvmPlatform file.fileType == JavaClassFileType.INSTANCE -> platform = JvmPlatform
else if (isKotlinMetadataFile(file)) isKotlinMetadataFile(file) -> platform = TargetPlatform.Default
platform = TargetPlatform.Default KotlinJavaScriptLibraryDetectionUtil.isJsFileWithMetadata(file) -> platform = JsPlatform
else if (KotlinJavaScriptLibraryDetectionUtil.isJsFileWithMetadata(file)) }
platform = JsPlatform
platform == null platform == null
} }
@@ -129,16 +129,12 @@ class KotlinSuppressIntentionAction private constructor(
val args = entry.valueArgumentList val args = entry.valueArgumentList
val psiFactory = KtPsiFactory(entry) val psiFactory = KtPsiFactory(entry)
val newArgList = psiFactory.createCallArguments("($id)") val newArgList = psiFactory.createCallArguments("($id)")
if (args == null) { when {
// new argument list args == null -> // new argument list
entry.addAfter(newArgList, entry.lastChild) entry.addAfter(newArgList, entry.lastChild)
} args.arguments.isEmpty() -> // replace '()' with a new argument list
else if (args.arguments.isEmpty()) {
// replace '()' with a new argument list
args.replace(newArgList) args.replace(newArgList)
} else -> args.addArgument(newArgList.arguments[0])
else {
args.addArgument(newArgList.arguments[0])
} }
} }
@@ -151,14 +151,10 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName:
val file = ref.containingKtFile val file = ref.containingKtFile
var result: Result = Result.NothingFound var result: Result = Result.NothingFound
val filePackage = file.packageFqName.asString() val filePackage = file.packageFqName.asString()
if (filePackage == targetPackage) { when (filePackage) {
result = result.changeTo(Result.Found) targetPackage -> result = result.changeTo(Result.Found)
} in conflictingPackages -> result = result.changeTo(Result.FoundOther)
else if (filePackage in conflictingPackages) { in packagesWithTypeAliases -> return UNSURE
result = result.changeTo(Result.FoundOther)
}
else if (filePackage in packagesWithTypeAliases) {
return UNSURE
} }
for (importPath in file.getDefaultImports()) { for (importPath in file.getDefaultImports()) {
@@ -202,14 +198,10 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName:
} }
} }
else { else {
if (qName?.asString() == targetPackage) { when {
return result.changeTo(Result.Found) qName?.asString() == targetPackage -> return result.changeTo(Result.Found)
} qName?.asString() in conflictingPackages -> return result.changeTo(Result.FoundOther)
else if (qName?.asString() in conflictingPackages) { qName?.asString() in packagesWithTypeAliases -> return Result.Ambiguity
return result.changeTo(Result.FoundOther)
}
else if (qName?.asString() in packagesWithTypeAliases) {
return Result.Ambiguity
} }
} }
return result return result
@@ -276,12 +276,11 @@ class BasicLookupElementFactory(
appendTailText(" for $receiverPresentation") appendTailText(" for $receiverPresentation")
val container = descriptor.containingDeclaration val container = descriptor.containingDeclaration
val containerPresentation = if (container is ClassDescriptor) val containerPresentation = when (container) {
DescriptorUtils.getFqNameFromTopLevelClass(container).toString() is ClassDescriptor -> DescriptorUtils.getFqNameFromTopLevelClass(container).toString()
else if (container is PackageFragmentDescriptor) is PackageFragmentDescriptor -> container.fqName.toString()
container.fqName.toString() else -> null
else }
null
if (containerPresentation != null) { if (containerPresentation != null) {
appendTailText(" in $containerPresentation") appendTailText(" in $containerPresentation")
} }
@@ -96,22 +96,18 @@ class CompletionBindingContextProvider(project: Project) {
val psiElementsBeforeAndAfter = modificationScope?.let { collectPsiElementsBeforeAndAfter(modificationScope, inStatement) } val psiElementsBeforeAndAfter = modificationScope?.let { collectPsiElementsBeforeAndAfter(modificationScope, inStatement) }
val prevCompletionData = prevCompletionDataCache.value.data val prevCompletionData = prevCompletionDataCache.value.data
if (prevCompletionData == null) { when {
prevCompletionData == null ->
log("No up-to-date data from previous completion\n") log("No up-to-date data from previous completion\n")
} block != prevCompletionData.block ->
else if (block != prevCompletionData.block) {
log("Not in the same block\n") log("Not in the same block\n")
} prevStatement != prevCompletionData.prevStatement ->
else if (prevStatement != prevCompletionData.prevStatement) {
log("Previous statement is not the same\n") log("Previous statement is not the same\n")
} psiElementsBeforeAndAfter != prevCompletionData.psiElementsBeforeAndAfter ->
else if (psiElementsBeforeAndAfter != prevCompletionData.psiElementsBeforeAndAfter) {
log("PSI-tree has changed inside current scope\n") log("PSI-tree has changed inside current scope\n")
} inStatement.isTooComplex() ->
else if (inStatement.isTooComplex()) {
log("Current statement is too complex to use optimization\n") log("Current statement is too complex to use optimization\n")
} else -> {
else {
log("Statement position is the same - analyzing only one statement:\n${inStatement.text.prependIndent(" ")}\n") log("Statement position is the same - analyzing only one statement:\n${inStatement.text.prependIndent(" ")}\n")
LOG.debug("Reusing data from completion of \"${prevCompletionData.debugText}\"") LOG.debug("Reusing data from completion of \"${prevCompletionData.debugText}\"")
@@ -123,6 +119,7 @@ class CompletionBindingContextProvider(project: Project) {
// we do not update prevCompletionDataCache because the same data should work // we do not update prevCompletionDataCache because the same data should work
return CompositeBindingContext.create(listOf(statementContext, prevCompletionData.bindingContext)) return CompositeBindingContext.create(listOf(statementContext, prevCompletionData.bindingContext))
} }
}
val bindingContext = resolutionFacade.analyze(position.parentsWithSelf.firstIsInstance<KtElement>(), BodyResolveMode.PARTIAL_FOR_COMPLETION) val bindingContext = resolutionFacade.analyze(position.parentsWithSelf.firstIsInstance<KtElement>(), BodyResolveMode.PARTIAL_FOR_COMPLETION)
prevCompletionDataCache.value.data = if (block != null && modificationScope != null) { prevCompletionDataCache.value.data = if (block != null && modificationScope != null) {
@@ -381,20 +381,17 @@ class LookupElementFactory(
return CallableWeight(bestWeight, receiverIndexToUse) return CallableWeight(bestWeight, receiverIndexToUse)
} }
private fun CallableDescriptor.callableWeightForReceiverType(receiverType: KotlinType, receiverParameterType: KotlinType): CallableWeightEnum? { private fun CallableDescriptor.callableWeightForReceiverType(
if (TypeUtils.equalTypes(receiverType, receiverParameterType)) { receiverType: KotlinType,
return when { receiverParameterType: KotlinType
): CallableWeightEnum? = when {
TypeUtils.equalTypes(receiverType, receiverParameterType) -> when {
isExtensionForTypeParameter() -> CallableWeightEnum.typeParameterExtension isExtensionForTypeParameter() -> CallableWeightEnum.typeParameterExtension
isExtension -> CallableWeightEnum.thisTypeExtension isExtension -> CallableWeightEnum.thisTypeExtension
else -> CallableWeightEnum.thisClassMember else -> CallableWeightEnum.thisClassMember
} }
} receiverType.isSubtypeOf(receiverParameterType) -> if (isExtension) CallableWeightEnum.baseTypeExtension else CallableWeightEnum.baseClassMember
else if (receiverType.isSubtypeOf(receiverParameterType)) { else -> null
return if (isExtension) CallableWeightEnum.baseTypeExtension else CallableWeightEnum.baseClassMember
}
else {
return null
}
} }
private fun CallableDescriptor.isExtensionForTypeParameter(): Boolean { private fun CallableDescriptor.isExtensionForTypeParameter(): Boolean {
@@ -343,12 +343,11 @@ class ExpectedInfos(
} }
val tail = if (argumentName == null) { val tail = if (argumentName == null) {
if (parameter == parameters.last()) when {
rparenthTail parameter == parameters.last() -> rparenthTail
else if (parameters.dropWhile { it != parameter }.drop(1).any(::needCommaForParameter)) parameters.dropWhile { it != parameter }.drop(1).any(::needCommaForParameter) -> Tail.COMMA
Tail.COMMA else -> null
else }
null
} }
else { else {
namedArgumentTail(argumentToParameter, argumentName, descriptor) namedArgumentTail(argumentToParameter, argumentName, descriptor)
@@ -404,12 +403,11 @@ class ExpectedInfos(
private fun namedArgumentTail(argumentToParameter: Map<ValueArgument, ValueParameterDescriptor>, argumentName: Name, descriptor: FunctionDescriptor): Tail? { private fun namedArgumentTail(argumentToParameter: Map<ValueArgument, ValueParameterDescriptor>, argumentName: Name, descriptor: FunctionDescriptor): Tail? {
val usedParameterNames = (argumentToParameter.values.map { it.name } + listOf(argumentName)).toSet() val usedParameterNames = (argumentToParameter.values.map { it.name } + listOf(argumentName)).toSet()
val notUsedParameters = descriptor.valueParameters.filter { it.name !in usedParameterNames } val notUsedParameters = descriptor.valueParameters.filter { it.name !in usedParameterNames }
return if (notUsedParameters.isEmpty()) return when {
Tail.RPARENTH // named arguments no supported for [] notUsedParameters.isEmpty() -> Tail.RPARENTH // named arguments no supported for []
else if (notUsedParameters.all { it.hasDefaultValue() }) notUsedParameters.all { it.hasDefaultValue() } -> null
null else -> Tail.COMMA
else }
Tail.COMMA
} }
private fun calculateForEqAndAssignment(expressionWithType: KtExpression): Collection<ExpectedInfo>? { private fun calculateForEqAndAssignment(expressionWithType: KtExpression): Collection<ExpectedInfo>? {
@@ -35,14 +35,13 @@ class ImportableFqNameClassifier(private val file: KtFile) {
for (import in file.importDirectives) { for (import in file.importDirectives) {
val importPath = import.importPath ?: continue val importPath = import.importPath ?: continue
val fqName = importPath.fqName val fqName = importPath.fqName
if (importPath.isAllUnder) { when {
allUnderImports.add(fqName) importPath.isAllUnder -> allUnderImports.add(fqName)
} !importPath.hasAlias() -> {
else if (!importPath.hasAlias()) {
preciseImports.add(fqName) preciseImports.add(fqName)
preciseImportPackages.add(fqName.parent()) preciseImportPackages.add(fqName.parent())
} else { }
excludedImports.add(fqName) else -> excludedImports.add(fqName)
// TODO: support aliased imports in completion // TODO: support aliased imports in completion
} }
} }
@@ -174,63 +174,29 @@ object KotlinNameSuggester {
val typeChecker = KotlinTypeChecker.DEFAULT val typeChecker = KotlinTypeChecker.DEFAULT
if (ErrorUtils.containsErrorType(type)) return if (ErrorUtils.containsErrorType(type)) return
if (typeChecker.equalTypes(builtIns.booleanType, type)) { when {
addName("b", validator) typeChecker.equalTypes(builtIns.booleanType, type) -> addName("b", validator)
} typeChecker.equalTypes(builtIns.intType, type) -> addName("i", validator)
else if (typeChecker.equalTypes(builtIns.intType, type)) { typeChecker.equalTypes(builtIns.byteType, type) -> addName("byte", validator)
addName("i", validator) typeChecker.equalTypes(builtIns.longType, type) -> addName("l", validator)
} typeChecker.equalTypes(builtIns.floatType, type) -> addName("fl", validator)
else if (typeChecker.equalTypes(builtIns.byteType, type)) { typeChecker.equalTypes(builtIns.doubleType, type) -> addName("d", validator)
addName("byte", validator) typeChecker.equalTypes(builtIns.shortType, type) -> addName("sh", validator)
} typeChecker.equalTypes(builtIns.charType, type) -> addName("c", validator)
else if (typeChecker.equalTypes(builtIns.longType, type)) { typeChecker.equalTypes(builtIns.stringType, type) -> addName("s", validator)
addName("l", validator) KotlinBuiltIns.isArray(type) || KotlinBuiltIns.isPrimitiveArray(type) -> {
}
else if (typeChecker.equalTypes(builtIns.floatType, type)) {
addName("fl", validator)
}
else if (typeChecker.equalTypes(builtIns.doubleType, type)) {
addName("d", validator)
}
else if (typeChecker.equalTypes(builtIns.shortType, type)) {
addName("sh", validator)
}
else if (typeChecker.equalTypes(builtIns.charType, type)) {
addName("c", validator)
}
else if (typeChecker.equalTypes(builtIns.stringType, type)) {
addName("s", validator)
}
else if (KotlinBuiltIns.isArray(type) || KotlinBuiltIns.isPrimitiveArray(type)) {
val elementType = builtIns.getArrayElementType(type) val elementType = builtIns.getArrayElementType(type)
if (typeChecker.equalTypes(builtIns.booleanType, elementType)) { when {
addName("booleans", validator) typeChecker.equalTypes(builtIns.booleanType, elementType) -> addName("booleans", validator)
} typeChecker.equalTypes(builtIns.intType, elementType) -> addName("ints", validator)
else if (typeChecker.equalTypes(builtIns.intType, elementType)) { typeChecker.equalTypes(builtIns.byteType, elementType) -> addName("bytes", validator)
addName("ints", validator) typeChecker.equalTypes(builtIns.longType, elementType) -> addName("longs", validator)
} typeChecker.equalTypes(builtIns.floatType, elementType) -> addName("floats", validator)
else if (typeChecker.equalTypes(builtIns.byteType, elementType)) { typeChecker.equalTypes(builtIns.doubleType, elementType) -> addName("doubles", validator)
addName("bytes", validator) typeChecker.equalTypes(builtIns.shortType, elementType) -> addName("shorts", validator)
} typeChecker.equalTypes(builtIns.charType, elementType) -> addName("chars", validator)
else if (typeChecker.equalTypes(builtIns.longType, elementType)) { typeChecker.equalTypes(builtIns.stringType, elementType) -> addName("strings", validator)
addName("longs", validator) else -> {
}
else if (typeChecker.equalTypes(builtIns.floatType, elementType)) {
addName("floats", validator)
}
else if (typeChecker.equalTypes(builtIns.doubleType, elementType)) {
addName("doubles", validator)
}
else if (typeChecker.equalTypes(builtIns.shortType, elementType)) {
addName("shorts", validator)
}
else if (typeChecker.equalTypes(builtIns.charType, elementType)) {
addName("chars", validator)
}
else if (typeChecker.equalTypes(builtIns.stringType, elementType)) {
addName("strings", validator)
}
else {
val classDescriptor = TypeUtils.getClassDescriptor(elementType) val classDescriptor = TypeUtils.getClassDescriptor(elementType)
if (classDescriptor != null) { if (classDescriptor != null) {
val className = classDescriptor.name val className = classDescriptor.name
@@ -238,10 +204,9 @@ object KotlinNameSuggester {
} }
} }
} }
else if (type.isFunctionType) {
addName("function", validator)
} }
else { type.isFunctionType -> addName("function", validator)
else -> {
val descriptor = type.constructor.declarationDescriptor val descriptor = type.constructor.declarationDescriptor
if (descriptor != null) { if (descriptor != null) {
val className = descriptor.name val className = descriptor.name
@@ -251,6 +216,7 @@ object KotlinNameSuggester {
} }
} }
} }
}
private val ACCESSOR_PREFIXES = arrayOf("get", "is", "set") private val ACCESSOR_PREFIXES = arrayOf("get", "is", "set")
@@ -204,25 +204,24 @@ fun KtModifierListOwner.setVisibility(visibilityModifier: KtModifierKeywordToken
} }
fun KtDeclaration.implicitVisibility(): KtModifierKeywordToken? = fun KtDeclaration.implicitVisibility(): KtModifierKeywordToken? =
if (this is KtConstructor<*>) { when {
this is KtConstructor<*> -> {
val klass = getContainingClassOrObject() val klass = getContainingClassOrObject()
if (klass is KtClass && (klass.isEnum() || klass.isSealed())) KtTokens.PRIVATE_KEYWORD if (klass is KtClass && (klass.isEnum() || klass.isSealed())) KtTokens.PRIVATE_KEYWORD
else KtTokens.DEFAULT_VISIBILITY_KEYWORD else KtTokens.DEFAULT_VISIBILITY_KEYWORD
} }
else if (hasModifier(KtTokens.OVERRIDE_KEYWORD)) { hasModifier(KtTokens.OVERRIDE_KEYWORD) -> {
(resolveToDescriptor(BodyResolveMode.PARTIAL) as? CallableMemberDescriptor) (resolveToDescriptor(BodyResolveMode.PARTIAL) as? CallableMemberDescriptor)
?.overriddenDescriptors ?.overriddenDescriptors
?.let { OverridingUtil.findMaxVisibility(it) } ?.let { OverridingUtil.findMaxVisibility(it) }
?.toKeywordToken() ?.toKeywordToken()
} }
else { else -> {
KtTokens.DEFAULT_VISIBILITY_KEYWORD KtTokens.DEFAULT_VISIBILITY_KEYWORD
} }
}
fun KtModifierListOwner.canBePrivate(): Boolean { fun KtModifierListOwner.canBePrivate() = modifierList?.hasModifier(KtTokens.ABSTRACT_KEYWORD) != true
if (modifierList?.hasModifier(KtTokens.ABSTRACT_KEYWORD) ?: false) return false
return true
}
fun KtModifierListOwner.canBeProtected(): Boolean { fun KtModifierListOwner.canBeProtected(): Boolean {
val parent = this.parent val parent = this.parent
@@ -75,12 +75,12 @@ class MavenPluginSourcesMoveToExecutionIntention : PsiElementBaseIntentionAction
val domElement = DomManager.getDomManager(project).getDomElement(tag) as? GenericDomValue<*> ?: return val domElement = DomManager.getDomManager(project).getDomElement(tag) as? GenericDomValue<*> ?: return
val dir = domElement.rawText ?: return val dir = domElement.rawText ?: return
val relevantExecutions = if (domElement.getParentOfType(MavenDomBuild::class.java, false)?.sourceDirectory === domElement) { val relevantExecutions = when {
domElement.getParentOfType(MavenDomBuild::class.java, false)?.sourceDirectory === domElement ->
pomFile.findKotlinExecutions(PomFile.KotlinGoals.Compile, PomFile.KotlinGoals.Js) pomFile.findKotlinExecutions(PomFile.KotlinGoals.Compile, PomFile.KotlinGoals.Js)
} else if (domElement.getParentOfType(MavenDomBuild::class.java, false)?.testSourceDirectory === domElement) { domElement.getParentOfType(MavenDomBuild::class.java, false)?.testSourceDirectory === domElement ->
pomFile.findKotlinExecutions(PomFile.KotlinGoals.TestCompile, PomFile.KotlinGoals.TestJs) pomFile.findKotlinExecutions(PomFile.KotlinGoals.TestCompile, PomFile.KotlinGoals.TestJs)
} else { else -> emptyList()
emptyList()
} }
if (relevantExecutions.isNotEmpty()) { if (relevantExecutions.isNotEmpty()) {
@@ -263,19 +263,11 @@ abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProj
targetFile: File, targetFile: File,
jarType: OrderRootType, jarType: OrderRootType,
useBundled: Boolean useBundled: Boolean
): FileState { ): FileState = when {
if (targetFile.exists()) { targetFile.exists() -> FileState.EXISTS
return FileState.EXISTS getPathFromLibrary(project, jarType) != null -> FileState.COPY
} useBundled -> FileState.DO_NOT_COPY
else if (getPathFromLibrary(project, jarType) != null) { else -> FileState.COPY
return FileState.COPY
}
else if (useBundled) {
return FileState.DO_NOT_COPY
}
else {
return FileState.COPY
}
} }
private fun getPathToCopyFileTo( private fun getPathToCopyFileTo(
@@ -120,13 +120,14 @@ class DebuggerClassNameProvider(
} }
is KtClassOrObject -> { is KtClassOrObject -> {
val enclosingElementForLocal = runReadAction { KtPsiUtil.getEnclosingElementForLocalDeclaration(element) } val enclosingElementForLocal = runReadAction { KtPsiUtil.getEnclosingElementForLocalDeclaration(element) }
if (enclosingElementForLocal != null) { // A local class when {
enclosingElementForLocal != null ->
// A local class
getOuterClassNamesForElement(enclosingElementForLocal) getOuterClassNamesForElement(enclosingElementForLocal)
} runReadAction { element.isObjectLiteral() } ->
else if (runReadAction { element.isObjectLiteral() }) {
getOuterClassNamesForElement(element.relevantParentInReadAction) getOuterClassNamesForElement(element.relevantParentInReadAction)
} else ->
else { // Guaranteed to be non-local class or object // Guaranteed to be non-local class or object
element.readAction { element.readAction {
if (it is KtClass && runReadAction { it.isInterface() }) { if (it is KtClass && runReadAction { it.isInterface() }) {
val name = getNameForNonLocalClass(it) val name = getNameForNonLocalClass(it)
@@ -300,13 +300,12 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour
val jdiValue = when (this) { val jdiValue = when (this) {
is ValueReturned -> result is ValueReturned -> result
is ExceptionThrown -> { is ExceptionThrown -> {
if (this.kind == ExceptionThrown.ExceptionKind.FROM_EVALUATED_CODE) { when {
this.kind == ExceptionThrown.ExceptionKind.FROM_EVALUATED_CODE ->
exception(InvocationException(this.exception.value as ObjectReference)) exception(InvocationException(this.exception.value as ObjectReference))
} this.kind == ExceptionThrown.ExceptionKind.BROKEN_CODE ->
else if (this.kind == ExceptionThrown.ExceptionKind.BROKEN_CODE) {
throw exception.value as Throwable throw exception.value as Throwable
} else ->
else {
exception(exception.toString()) exception(exception.toString())
} }
} }
@@ -187,7 +187,8 @@ private class TemplateTokenSequence(private val inputString: String) : Sequence<
val wrapped = '"' + input.substring(from) + '"' val wrapped = '"' + input.substring(from) + '"'
val lexer = KotlinLexer().apply { start(wrapped) }.apply { advance() } val lexer = KotlinLexer().apply { start(wrapped) }.apply { advance() }
if (lexer.tokenType == KtTokens.SHORT_TEMPLATE_ENTRY_START) { when (lexer.tokenType) {
KtTokens.SHORT_TEMPLATE_ENTRY_START -> {
lexer.advance() lexer.advance()
return if (lexer.tokenType == KtTokens.IDENTIFIER) { return if (lexer.tokenType == KtTokens.IDENTIFIER) {
from + lexer.tokenEnd - 1 from + lexer.tokenEnd - 1
@@ -196,7 +197,7 @@ private class TemplateTokenSequence(private val inputString: String) : Sequence<
-1 -1
} }
} }
else if (lexer.tokenType == KtTokens.LONG_TEMPLATE_ENTRY_START) { KtTokens.LONG_TEMPLATE_ENTRY_START -> {
var depth = 0 var depth = 0
while (lexer.tokenType != null) { while (lexer.tokenType != null) {
if (lexer.tokenType == KtTokens.LONG_TEMPLATE_ENTRY_START) { if (lexer.tokenType == KtTokens.LONG_TEMPLATE_ENTRY_START) {
@@ -212,8 +213,7 @@ private class TemplateTokenSequence(private val inputString: String) : Sequence<
} }
return -1 return -1
} }
else { else -> return -1
return -1
} }
} }
@@ -40,11 +40,12 @@ class KotlinRainbowVisitor : RainbowVisitor() {
override fun clone() = KotlinRainbowVisitor() override fun clone() = KotlinRainbowVisitor()
override fun visit(element: PsiElement) { override fun visit(element: PsiElement) {
if (element.isRainbowDeclaration()) { when {
element.isRainbowDeclaration() -> {
val rainbowElement = (element as KtNamedDeclaration).nameIdentifier ?: return val rainbowElement = (element as KtNamedDeclaration).nameIdentifier ?: return
addRainbowHighlight(element, rainbowElement) addRainbowHighlight(element, rainbowElement)
} }
else if (element is KtSimpleNameExpression) { element is KtSimpleNameExpression -> {
val qualifiedExpression = PsiTreeUtil.getParentOfType(element, KtQualifiedExpression::class.java, true, val qualifiedExpression = PsiTreeUtil.getParentOfType(element, KtQualifiedExpression::class.java, true,
KtLambdaExpression::class.java, KtValueArgumentList::class.java) KtLambdaExpression::class.java, KtValueArgumentList::class.java)
if (qualifiedExpression?.selectorExpression?.isAncestor(element) == true) return if (qualifiedExpression?.selectorExpression?.isAncestor(element) == true) return
@@ -62,13 +63,14 @@ class KotlinRainbowVisitor : RainbowVisitor() {
} }
} }
} }
else if (element is KDocName) { element is KDocName -> {
val target = element.reference?.resolve() ?: return val target = element.reference?.resolve() ?: return
if (target.isRainbowDeclaration()) { if (target.isRainbowDeclaration()) {
addRainbowHighlight(target, element, KDOC_LINK) addRainbowHighlight(target, element, KDOC_LINK)
} }
} }
} }
}
private fun addRainbowHighlight(target: PsiElement, rainbowElement: PsiElement, private fun addRainbowHighlight(target: PsiElement, rainbowElement: PsiElement,
attributesKey: TextAttributesKey? = null) { attributesKey: TextAttributesKey? = null) {
@@ -95,14 +95,10 @@ class KotlinUnusedImportInspection : AbstractKotlinInspection() {
val importPath = directive.importPath ?: continue val importPath = directive.importPath ?: continue
if (importPath.alias != null) continue // highlighting of unused alias imports not supported yet if (importPath.alias != null) continue // highlighting of unused alias imports not supported yet
val isUsed = if (!importPaths.add(importPath)) { val isUsed = when {
false !importPaths.add(importPath) -> false
} importPath.isAllUnder -> importPath.fqName in parentFqNames
else if (importPath.isAllUnder) { else -> importPath.fqName in fqNames
importPath.fqName in parentFqNames
}
else {
importPath.fqName in fqNames
} }
if (!isUsed) { if (!isUsed) {
@@ -72,7 +72,11 @@ class NullableBooleanElvisInspection : AbstractKotlinInspection(), CleanupLocalI
val constPart = element.right as? KtConstantExpression ?: return val constPart = element.right as? KtConstantExpression ?: return
val exprPart = element.left ?: return val exprPart = element.left ?: return
val constValue = if (KtPsiUtil.isTrueConstant(constPart)) true else if (KtPsiUtil.isFalseConstant(constPart)) false else return val constValue = when {
KtPsiUtil.isTrueConstant(constPart) -> true
KtPsiUtil.isFalseConstant(constPart) -> false
else -> return
}
val equalityCheckExpression = element.replaced(KtPsiFactory(constPart).buildExpression { val equalityCheckExpression = element.replaced(KtPsiFactory(constPart).buildExpression {
appendExpression(exprPart) appendExpression(exprPart)
appendFixedText(if (constValue) " != false" else " == true") appendFixedText(if (constValue) " != false" else " == true")
@@ -47,7 +47,11 @@ class NullableBooleanEqualityCheckToElvisIntention : SelfTargetingIntention<KtBi
val constPart = element.left as? KtConstantExpression ?: val constPart = element.left as? KtConstantExpression ?:
element.right as? KtConstantExpression ?: return element.right as? KtConstantExpression ?: return
val exprPart = (if (element.right == constPart) element.left else element.right) ?: return val exprPart = (if (element.right == constPart) element.left else element.right) ?: return
val constValue = if (KtPsiUtil.isTrueConstant(constPart)) true else if (KtPsiUtil.isFalseConstant(constPart)) false else return val constValue = when {
KtPsiUtil.isTrueConstant(constPart) -> true
KtPsiUtil.isFalseConstant(constPart) -> false
else -> return
}
val factory = KtPsiFactory(constPart) val factory = KtPsiFactory(constPart)
val elvis = factory.createExpressionByPattern("$0 ?: ${!constValue}", exprPart) val elvis = factory.createExpressionByPattern("$0 ?: ${!constValue}", exprPart)
@@ -168,14 +168,11 @@ data class IfThenToSelectData(
if (condition is KtIsExpression) newReceiver!! else baseClause if (condition is KtIsExpression) newReceiver!! else baseClause
} }
else { else {
if (condition is KtIsExpression) { when {
(baseClause as KtDotQualifiedExpression).replaceFirstReceiver( condition is KtIsExpression -> (baseClause as KtDotQualifiedExpression).replaceFirstReceiver(
factory, newReceiver!!, safeAccess = true) factory, newReceiver!!, safeAccess = true)
} hasImplicitReceiver() -> factory.createExpressionByPattern("this?.$0", baseClause).insertSafeCalls(factory)
else if (hasImplicitReceiver()) { else -> baseClause.insertSafeCalls(factory)
factory.createExpressionByPattern("this?.$0", baseClause).insertSafeCalls(factory)
} else {
baseClause.insertSafeCalls(factory)
} }
} }
} }
@@ -116,14 +116,10 @@ class MaxOrMinTransformation(
val functionName = if (isMax) "max" else "min" val functionName = if (isMax) "max" else "min"
val arguments = assignment.right.extractStaticFunctionCallArguments("java.lang.Math." + functionName) ?: return null val arguments = assignment.right.extractStaticFunctionCallArguments("java.lang.Math." + functionName) ?: return null
if (arguments.size != 2) return null if (arguments.size != 2) return null
val value = if (arguments[0].isVariableReference(variableInitialization.variable)) { val value = when {
arguments[1] ?: return null arguments[0].isVariableReference(variableInitialization.variable) -> arguments[1] ?: return null
} arguments[1].isVariableReference(variableInitialization.variable) -> arguments[0] ?: return null
else if (arguments[1].isVariableReference(variableInitialization.variable)) { else -> return null
arguments[0] ?: return null
}
else {
return null
} }
val mapTransformation = if (value.isVariableReference(state.inputVariable)) val mapTransformation = if (value.isVariableReference(state.inputVariable))
@@ -148,14 +144,10 @@ class MaxOrMinTransformation(
if (comparison !in setOf(KtTokens.GT, KtTokens.LT, KtTokens.GTEQ, KtTokens.LTEQ)) return null if (comparison !in setOf(KtTokens.GT, KtTokens.LT, KtTokens.GTEQ, KtTokens.LTEQ)) return null
val left = condition.left as? KtNameReferenceExpression ?: return null val left = condition.left as? KtNameReferenceExpression ?: return null
val right = condition.right as? KtNameReferenceExpression ?: return null val right = condition.right as? KtNameReferenceExpression ?: return null
val otherHand = if (left.isVariableReference(inputVariable)) { val otherHand = when {
right left.isVariableReference(inputVariable) -> right
} right.isVariableReference(inputVariable) -> left
else if (right.isVariableReference(inputVariable)) { else -> return null
left
}
else {
return null
} }
val variableInitialization = otherHand.findVariableInitializationBeforeLoop(loop, checkNoOtherUsagesInLoop = false) val variableInitialization = otherHand.findVariableInitializationBeforeLoop(loop, checkNoOtherUsagesInLoop = false)
@@ -163,14 +155,10 @@ class MaxOrMinTransformation(
if (!assignmentTarget.isVariableReference(variableInitialization.variable)) return null if (!assignmentTarget.isVariableReference(variableInitialization.variable)) return null
val valueToBeVariable = if (valueAssignedIfTrue.isVariableReference(inputVariable)) { val valueToBeVariable = when {
valueAssignedIfFalse valueAssignedIfTrue.isVariableReference(inputVariable) -> valueAssignedIfFalse
} valueAssignedIfFalse.isVariableReference(inputVariable) -> valueAssignedIfTrue
else if (valueAssignedIfFalse.isVariableReference(inputVariable)) { else -> return null
valueAssignedIfTrue
}
else {
return null
} }
if (valueToBeVariable != null && !valueToBeVariable.isVariableReference(variableInitialization.variable)) return null if (valueToBeVariable != null && !valueToBeVariable.isVariableReference(variableInitialization.variable)) return null
@@ -54,14 +54,10 @@ open class KotlinDefaultNamedDeclarationPresentation(private val declaration: Kt
qualifiedContainer qualifiedContainer
} }
val receiverTypeRef = (declaration as? KtCallableDeclaration)?.receiverTypeReference val receiverTypeRef = (declaration as? KtCallableDeclaration)?.receiverTypeReference
if (receiverTypeRef != null) { return when {
return "(for " + receiverTypeRef.text + " in " + containerText + ")" receiverTypeRef != null -> "(for " + receiverTypeRef.text + " in " + containerText + ")"
} parent is KtFile -> "($containerText)"
else if (parent is KtFile) { else -> "(in $containerText)"
return "(" + containerText + ")"
}
else {
return "(in " + containerText + ")"
} }
} }
@@ -63,15 +63,13 @@ abstract class ChangeFunctionSignatureFix(
val argumentName = argument.getArgumentName() val argumentName = argument.getArgumentName()
val expression = argument.getArgumentExpression() val expression = argument.getArgumentExpression()
return if (argumentName != null) { return when {
KotlinNameSuggester.suggestNameByName(argumentName.asName.asString(), validator) argumentName != null -> KotlinNameSuggester.suggestNameByName(argumentName.asName.asString(), validator)
} expression != null -> {
else if (expression != null) {
val bindingContext = expression.analyze(BodyResolveMode.PARTIAL) val bindingContext = expression.analyze(BodyResolveMode.PARTIAL)
KotlinNameSuggester.suggestNamesByExpressionAndType(expression, null, bindingContext, validator, "param").first() KotlinNameSuggester.suggestNamesByExpressionAndType(expression, null, bindingContext, validator, "param").first()
} }
else { else -> KotlinNameSuggester.suggestNameByName("param", validator)
KotlinNameSuggester.suggestNameByName("param", validator)
} }
} }
@@ -100,16 +100,20 @@ class ReplaceInfixOrOperatorCallFix(
val parent = expression.parent val parent = expression.parent
return when (parent) { return when (parent) {
is KtBinaryExpression -> { is KtBinaryExpression -> {
if (parent.left == null || parent.right == null) null when {
else if (parent.operationToken == KtTokens.EQ) null parent.left == null || parent.right == null -> null
else if (parent.operationToken in OperatorConventions.COMPARISON_OPERATIONS) null parent.operationToken == KtTokens.EQ -> null
else ReplaceInfixOrOperatorCallFix(parent, parent.shouldHaveNotNullType()) parent.operationToken in OperatorConventions.COMPARISON_OPERATIONS -> null
else -> ReplaceInfixOrOperatorCallFix(parent, parent.shouldHaveNotNullType())
}
} }
is KtCallExpression -> { is KtCallExpression -> {
if (parent.calleeExpression == null) null when {
else if (parent.parent is KtQualifiedExpression) null parent.calleeExpression == null -> null
else if (parent.getResolvedCall(parent.analyze())?.getImplicitReceiverValue() != null) null parent.parent is KtQualifiedExpression -> null
else ReplaceInfixOrOperatorCallFix(parent, parent.shouldHaveNotNullType()) parent.getResolvedCall(parent.analyze())?.getImplicitReceiverValue() != null -> null
else -> ReplaceInfixOrOperatorCallFix(parent, parent.shouldHaveNotNullType())
}
} }
else -> null else -> null
} }
@@ -41,14 +41,10 @@ class SpecifyTypeExplicitlyFix : PsiElementBaseIntentionAction() {
override fun isAvailable(project: Project, editor: Editor, element: PsiElement): Boolean { override fun isAvailable(project: Project, editor: Editor, element: PsiElement): Boolean {
val declaration = declarationByElement(element) val declaration = declarationByElement(element)
if (declaration is KtProperty) { text = when (declaration) {
text = "Specify type explicitly" is KtProperty -> "Specify type explicitly"
} is KtNamedFunction -> "Specify return type explicitly"
else if (declaration is KtNamedFunction) { else -> return false
text = "Specify return type explicitly"
}
else {
return false
} }
return !SpecifyTypeExplicitlyIntention.getTypeForDeclaration(declaration).isError return !SpecifyTypeExplicitlyIntention.getTypeForDeclaration(declaration).isError
@@ -96,19 +96,23 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration)
val nativeAnnotations = ArrayList<KtAnnotationEntry>() val nativeAnnotations = ArrayList<KtAnnotationEntry>()
declaration.modifierList?.annotationEntries?.forEach { declaration.modifierList?.annotationEntries?.forEach {
if (it.isJsAnnotation(PredefinedAnnotation.NATIVE_GETTER)) { when {
it.isJsAnnotation(PredefinedAnnotation.NATIVE_GETTER) -> {
isGetter = true isGetter = true
nativeAnnotations.add(it) nativeAnnotations.add(it)
} else if (it.isJsAnnotation(PredefinedAnnotation.NATIVE_SETTER)) { }
it.isJsAnnotation(PredefinedAnnotation.NATIVE_SETTER) -> {
isSetter = true isSetter = true
nativeAnnotations.add(it) nativeAnnotations.add(it)
} else if (it.isJsAnnotation(PredefinedAnnotation.NATIVE_INVOKE)) { }
it.isJsAnnotation(PredefinedAnnotation.NATIVE_INVOKE) -> {
isInvoke = true isInvoke = true
nativeAnnotations.add(it) nativeAnnotations.add(it)
} else if (it.isJsAnnotation(PredefinedAnnotation.NATIVE)) { }
it.isJsAnnotation(PredefinedAnnotation.NATIVE) -> {
nativeAnnotations.add(it) nativeAnnotations.add(it)
nativeAnnotation = it nativeAnnotation = it
}
} }
} }
return JsNativeAnnotations(nativeAnnotations, nativeAnnotation, isGetter, isSetter, isInvoke) return JsNativeAnnotations(nativeAnnotations, nativeAnnotation, isGetter, isSetter, isInvoke)
@@ -122,12 +126,14 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration)
val ktPsiFactory = KtPsiFactory(declaration) val ktPsiFactory = KtPsiFactory(declaration)
val body = ktPsiFactory.buildExpression { val body = ktPsiFactory.buildExpression {
appendName(Name.identifier("asDynamic")) appendName(Name.identifier("asDynamic"))
if (annotations.isGetter) { when {
annotations.isGetter -> {
appendFixedText("()") appendFixedText("()")
if (declaration is KtNamedFunction) { if (declaration is KtNamedFunction) {
appendParameters(declaration, "[", "]") appendParameters(declaration, "[", "]")
} }
} else if (annotations.isSetter) { }
annotations.isSetter -> {
appendFixedText("()") appendFixedText("()")
if (declaration is KtNamedFunction) { if (declaration is KtNamedFunction) {
appendParameters(declaration, "[", "]", skipLast = true) appendParameters(declaration, "[", "]", skipLast = true)
@@ -136,12 +142,14 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration)
appendName(it) appendName(it)
} }
} }
} else if (annotations.isInvoke) { }
annotations.isInvoke -> {
appendFixedText("()") appendFixedText("()")
if (declaration is KtNamedFunction) { if (declaration is KtNamedFunction) {
appendParameters(declaration, "(", ")") appendParameters(declaration, "(", ")")
} }
} else { }
else -> {
appendFixedText("().") appendFixedText("().")
appendName(name) appendName(name)
if (declaration is KtNamedFunction) { if (declaration is KtNamedFunction) {
@@ -149,6 +157,7 @@ class MigrateExternalExtensionFix(declaration: KtNamedDeclaration)
} }
} }
} }
}
if (declaration is KtNamedFunction) { if (declaration is KtNamedFunction) {
declaration.bodyExpression?.delete() declaration.bodyExpression?.delete()
@@ -122,33 +122,19 @@ class KotlinChangeSignatureData(
} }
} }
override fun getParameters(): List<KotlinParameterInfo> { override fun getParameters(): List<KotlinParameterInfo> = parameters
return parameters
override fun getName() = when (baseDescriptor) {
is ConstructorDescriptor -> baseDescriptor.containingDeclaration.name.asString()
is AnonymousFunctionDescriptor -> ""
else -> baseDescriptor.name.asString()
} }
override fun getName(): String { override fun getParametersCount(): Int = baseDescriptor.valueParameters.size
if (baseDescriptor is ConstructorDescriptor) {
return baseDescriptor.containingDeclaration.name.asString()
}
else if (baseDescriptor is AnonymousFunctionDescriptor) {
return ""
}
else {
return baseDescriptor.name.asString()
}
}
override fun getParametersCount(): Int { override fun getVisibility(): Visibility = baseDescriptor.visibility
return baseDescriptor.valueParameters.size
}
override fun getVisibility(): Visibility { override fun getMethod(): PsiElement = baseDeclaration
return baseDescriptor.visibility
}
override fun getMethod(): PsiElement {
return baseDeclaration
}
override fun canChangeVisibility(): Boolean { override fun canChangeVisibility(): Boolean {
if (DescriptorUtils.isLocal(baseDescriptor)) return false if (DescriptorUtils.isLocal(baseDescriptor)) return false
@@ -156,15 +142,10 @@ class KotlinChangeSignatureData(
return !(baseDescriptor is AnonymousFunctionDescriptor || parent is ClassDescriptor && parent.kind == ClassKind.INTERFACE) return !(baseDescriptor is AnonymousFunctionDescriptor || parent is ClassDescriptor && parent.kind == ClassKind.INTERFACE)
} }
override fun canChangeParameters(): Boolean { override fun canChangeParameters() = true
return true
}
override fun canChangeName(): Boolean { override fun canChangeName() = !(baseDescriptor is ConstructorDescriptor || baseDescriptor is AnonymousFunctionDescriptor)
return !(baseDescriptor is ConstructorDescriptor || baseDescriptor is AnonymousFunctionDescriptor)
}
override fun canChangeReturnType(): MethodDescriptor.ReadWriteOption { override fun canChangeReturnType(): MethodDescriptor.ReadWriteOption =
return if (baseDescriptor is ConstructorDescriptor) MethodDescriptor.ReadWriteOption.None else MethodDescriptor.ReadWriteOption.ReadWrite if (baseDescriptor is ConstructorDescriptor) MethodDescriptor.ReadWriteOption.None else MethodDescriptor.ReadWriteOption.ReadWrite
}
} }
@@ -248,18 +248,20 @@ class KotlinChangeSignatureDialog(
return JBTableRow { column -> return JBTableRow { column ->
val columnInfo = parametersTableModel.columnInfos[column] val columnInfo = parametersTableModel.columnInfos[column]
if (KotlinPrimaryConstructorParameterTableModel.isValVarColumn(columnInfo)) when {
KotlinPrimaryConstructorParameterTableModel.isValVarColumn(columnInfo) ->
(components[column] as @Suppress("NO_TYPE_ARGUMENTS_ON_RHS") JComboBox).selectedItem (components[column] as @Suppress("NO_TYPE_ARGUMENTS_ON_RHS") JComboBox).selectedItem
else if (KotlinCallableParameterTableModel.isTypeColumn(columnInfo)) KotlinCallableParameterTableModel.isTypeColumn(columnInfo) ->
item.typeCodeFragment item.typeCodeFragment
else if (KotlinCallableParameterTableModel.isNameColumn(columnInfo)) KotlinCallableParameterTableModel.isNameColumn(columnInfo) ->
(components[column] as EditorTextField).text (components[column] as EditorTextField).text
else if (KotlinCallableParameterTableModel.isDefaultValueColumn(columnInfo)) KotlinCallableParameterTableModel.isDefaultValueColumn(columnInfo) ->
item.defaultValueCodeFragment item.defaultValueCodeFragment
else else ->
null null
} }
} }
}
private fun getColumnWidth(letters: Int): Int { private fun getColumnWidth(letters: Int): Int {
var font = EditorColorsManager.getInstance().globalScheme.getFont(EditorFontType.PLAIN) var font = EditorColorsManager.getInstance().globalScheme.getFont(EditorFontType.PLAIN)
@@ -291,9 +293,11 @@ class KotlinChangeSignatureDialog(
override fun getPreferredFocusedComponent(): JComponent { override fun getPreferredFocusedComponent(): JComponent {
val me = mouseEvent val me = mouseEvent
val index = if (me != null) val index = when {
getEditorIndex(me.point.getX().toInt()) me != null -> getEditorIndex(me.point.getX().toInt())
else if (myMethod.kind === Kind.PRIMARY_CONSTRUCTOR) 1 else 0 myMethod.kind === Kind.PRIMARY_CONSTRUCTOR -> 1
else -> 0
}
val component = components[index] val component = components[index]
return if (component is EditorTextField) component.focusTarget else component return if (component is EditorTextField) component.focusTarget else component
} }
@@ -353,16 +353,12 @@ private fun makeCall(
) )
is Jump -> { is Jump -> {
if (outputValue.elementToInsertAfterCall == null) { when {
Collections.singletonList(psiFactory.createExpression(callText)) outputValue.elementToInsertAfterCall == null -> Collections.singletonList(psiFactory.createExpression(callText))
} outputValue.conditional -> Collections.singletonList(
else if (outputValue.conditional) {
Collections.singletonList(
psiFactory.createExpression("if ($callText) ${outputValue.elementToInsertAfterCall.text}") psiFactory.createExpression("if ($callText) ${outputValue.elementToInsertAfterCall.text}")
) )
} else -> listOf(
else {
listOf(
psiFactory.createExpression(callText), psiFactory.createExpression(callText),
newLine, newLine,
psiFactory.createExpression(outputValue.elementToInsertAfterCall.text!!) psiFactory.createExpression(outputValue.elementToInsertAfterCall.text!!)
@@ -134,13 +134,12 @@ fun IntroduceTypeAliasDescriptor.validate(): IntroduceTypeAliasDescriptorWithCon
val conflicts = MultiMap<PsiElement, String>() val conflicts = MultiMap<PsiElement, String>()
val originalType = originalData.originalTypeElement val originalType = originalData.originalTypeElement
if (name.isEmpty()) { when {
name.isEmpty() ->
conflicts.putValue(originalType, "No name provided for type alias") conflicts.putValue(originalType, "No name provided for type alias")
} !KotlinNameSuggester.isIdentifier(name) ->
else if (!KotlinNameSuggester.isIdentifier(name)) {
conflicts.putValue(originalType, "Type alias name must be a valid identifier: $name") conflicts.putValue(originalType, "Type alias name must be a valid identifier: $name")
} originalData.getTargetScope().findClassifier(Name.identifier(name), NoLookupLocation.FROM_IDE) != null ->
else if (originalData.getTargetScope().findClassifier(Name.identifier(name), NoLookupLocation.FROM_IDE) != null) {
conflicts.putValue(originalType, "Type $name already exists in the target scope") conflicts.putValue(originalType, "Type $name already exists in the target scope")
} }
@@ -97,12 +97,14 @@ class KotlinRunConfigurationProducer : RunConfigurationProducer<JetRunConfigurat
null -> null null -> null
is KtFile -> container.javaFileFacadeFqName.asString() is KtFile -> container.javaFileFacadeFqName.asString()
is KtClassOrObject -> { is KtClassOrObject -> {
if (!container.isValid) if (!container.isValid) {
null null
}
else if (container is KtObjectDeclaration && container.isCompanion()) { else if (container is KtObjectDeclaration && container.isCompanion()) {
val containerClass = container.getParentOfType<KtClass>(true) val containerClass = container.getParentOfType<KtClass>(true)
containerClass?.toLightClass()?.let { ClassUtil.getJVMClassName(it) } containerClass?.toLightClass()?.let { ClassUtil.getJVMClassName(it) }
} else { }
else {
container.toLightClass()?.let { ClassUtil.getJVMClassName(it) } container.toLightClass()?.let { ClassUtil.getJVMClassName(it) }
} }
} }
@@ -115,18 +115,20 @@ fun notifyOutdatedKotlinRuntime(project: Project, outdatedLibraries: Collection<
Notifications.Bus.notify(Notification(OUTDATED_RUNTIME_GROUP_DISPLAY_ID, "Outdated Kotlin Runtime", message, Notifications.Bus.notify(Notification(OUTDATED_RUNTIME_GROUP_DISPLAY_ID, "Outdated Kotlin Runtime", message,
NotificationType.WARNING, NotificationListener { notification, event -> NotificationType.WARNING, NotificationListener { notification, event ->
if (event.eventType == HyperlinkEvent.EventType.ACTIVATED) { if (event.eventType == HyperlinkEvent.EventType.ACTIVATED) {
if ("update" == event.description) { when {
"update" == event.description -> {
val outdatedLibraries = findOutdatedKotlinLibraries(project).map { it.library } val outdatedLibraries = findOutdatedKotlinLibraries(project).map { it.library }
ApplicationManager.getApplication().invokeLater { ApplicationManager.getApplication().invokeLater {
updateLibraries(project, outdatedLibraries) updateLibraries(project, outdatedLibraries)
} }
} }
else if ("ignore" == event.description) { "ignore" == event.description -> {
PropertiesComponent.getInstance(project).setValue(SUPPRESSED_PROPERTY_NAME, pluginVersion) PropertiesComponent.getInstance(project).setValue(SUPPRESSED_PROPERTY_NAME, pluginVersion)
} }
else { else -> {
throw AssertionError() throw AssertionError()
} }
}
notification.expire() notification.expire()
} }
}), project) }), project)
@@ -345,7 +345,8 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
if (target is KtLightMethod) { if (target is KtLightMethod) {
val origin = target.kotlinOrigin val origin = target.kotlinOrigin
val isTopLevel = origin?.getStrictParentOfType<KtClassOrObject>() == null val isTopLevel = origin?.getStrictParentOfType<KtClassOrObject>() == null
if (origin is KtProperty || origin is KtPropertyAccessor || origin is KtParameter) { when (origin) {
is KtProperty, is KtPropertyAccessor, is KtParameter -> {
val property = if (origin is KtPropertyAccessor) val property = if (origin is KtPropertyAccessor)
origin.parent as KtProperty origin.parent as KtProperty
else else
@@ -381,8 +382,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
} }
} }
} }
else if (origin is KtFunction) { is KtFunction -> if (isTopLevel) {
if (isTopLevel) {
result = if (origin.isExtensionDeclaration()) { result = if (origin.isExtensionDeclaration()) {
val qualifier = codeConverter.convertExpression(arguments.firstOrNull(), shouldParenthesize = true) val qualifier = codeConverter.convertExpression(arguments.firstOrNull(), shouldParenthesize = true)
MethodCallExpression.build(qualifier, MethodCallExpression.build(qualifier,
@@ -401,8 +401,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
} }
return return
} }
} null -> {
else if (origin == null){
val resolvedQualifier = (methodExpr.qualifier as? PsiReferenceExpression)?.resolve() val resolvedQualifier = (methodExpr.qualifier as? PsiReferenceExpression)?.resolve()
if (isFacadeClassFromLibrary(resolvedQualifier)) { if (isFacadeClassFromLibrary(resolvedQualifier)) {
result = if (target.isKotlinExtensionFunction()) { result = if (target.isKotlinExtensionFunction()) {
@@ -425,6 +424,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
} }
} }
} }
}
if (target is PsiMethod) { if (target is PsiMethod) {
val specialMethod = SpecialMethod.match(target, arguments.size, converter.services) val specialMethod = SpecialMethod.match(target, arguments.size, converter.services)
@@ -826,19 +826,19 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
val specialMethod = method?.let { SpecialMethod.match(it, callParams.size, converter.services) } val specialMethod = method?.let { SpecialMethod.match(it, callParams.size, converter.services) }
val statement: Statement val statement: Statement
if (expression.isConstructor) { when {
expression.isConstructor -> {
val argumentList = ArgumentList.withNoPrototype(callParams.map { it.first }) val argumentList = ArgumentList.withNoPrototype(callParams.map { it.first })
statement = MethodCallExpression.buildNonNull(null, convertMethodReferenceQualifier(qualifier), argumentList) statement = MethodCallExpression.buildNonNull(null, convertMethodReferenceQualifier(qualifier), argumentList)
} }
else if (specialMethod != null) { specialMethod != null -> {
val factory = PsiElementFactory.SERVICE.getInstance(converter.project) val factory = PsiElementFactory.SERVICE.getInstance(converter.project)
val fakeReceiver = receiver?.let { val fakeReceiver = receiver?.let {
val psiExpression = qualifier as? PsiExpression ?: factory.createExpressionFromText("fakeReceiver", null) val psiExpression = qualifier as? PsiExpression ?: factory.createExpressionFromText("fakeReceiver", null)
psiExpression.convertedExpression = it.first psiExpression.convertedExpression = it.first
psiExpression psiExpression
} }
val fakeParams = callParams.mapIndexed { val fakeParams = callParams.mapIndexed { i, param ->
i, param ->
with(factory.createExpressionFromText("fake$i", null)) { with(factory.createExpressionFromText("fake$i", null)) {
this.convertedExpression = param.first this.convertedExpression = param.first
this this
@@ -855,11 +855,12 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter {
val callData = SpecialMethod.ConvertCallData(fakeReceiver, fakeParams, emptyList(), null, null, null, patchedConverter) val callData = SpecialMethod.ConvertCallData(fakeReceiver, fakeParams, emptyList(), null, null, null, patchedConverter)
statement = specialMethod.convertCall(callData)!! statement = specialMethod.convertCall(callData)!!
} }
else { else -> {
val referenceName = expression.referenceName!! val referenceName = expression.referenceName!!
val argumentList = ArgumentList.withNoPrototype(callParams.map { it.first }) val argumentList = ArgumentList.withNoPrototype(callParams.map { it.first })
statement = MethodCallExpression.buildNonNull(receiver?.first, referenceName, argumentList) statement = MethodCallExpression.buildNonNull(receiver?.first, referenceName, argumentList)
} }
}
statement.assignNoPrototype() statement.assignNoPrototype()
@@ -104,13 +104,14 @@ class ForConverter(
statement.isInSingleLine()).assignNoPrototype() statement.isInSingleLine()).assignNoPrototype()
if (initializationConverted.isEmpty) return whileStatement if (initializationConverted.isEmpty) return whileStatement
val kind = if (statement.parents.filter { it !is PsiLabeledStatement }.first() !is PsiCodeBlock) { val kind = when {
statement.parents.filter { it !is PsiLabeledStatement }.first() !is PsiCodeBlock ->
WhileWithInitializationPseudoStatement.Kind.WITH_BLOCK WhileWithInitializationPseudoStatement.Kind.WITH_BLOCK
} hasNameConflict() ->
else if (hasNameConflict())
WhileWithInitializationPseudoStatement.Kind.WITH_RUN_BLOCK WhileWithInitializationPseudoStatement.Kind.WITH_RUN_BLOCK
else else ->
WhileWithInitializationPseudoStatement.Kind.SIMPLE WhileWithInitializationPseudoStatement.Kind.SIMPLE
}
return WhileWithInitializationPseudoStatement(initializationConverted, whileStatement, kind) return WhileWithInitializationPseudoStatement(initializationConverted, whileStatement, kind)
} }
@@ -266,13 +266,15 @@ class TypeConverter(val converter: Converter) {
override fun fromAnnotations(owner: PsiModifierListOwner): Nullability { override fun fromAnnotations(owner: PsiModifierListOwner): Nullability {
val manager = NullableNotNullManager.getInstance(owner.project) val manager = NullableNotNullManager.getInstance(owner.project)
return if (manager.isNotNull(owner, false/* we do not check bases because they are checked by callers of this method*/)) return when {
manager.isNotNull(owner, false/* we do not check bases because they are checked by callers of this method*/) ->
Nullability.NotNull Nullability.NotNull
else if (manager.isNullable(owner, false)) manager.isNullable(owner, false) ->
Nullability.Nullable Nullability.Nullable
else else ->
Nullability.Default Nullability.Default
} }
}
override fun forVariableTypeBeforeUsageSearch(variable: PsiVariable): Nullability { override fun forVariableTypeBeforeUsageSearch(variable: PsiVariable): Nullability {
val initializer = variable.initializer val initializer = variable.initializer
@@ -40,17 +40,11 @@ class TypeVisitor(
override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type { override fun visitPrimitiveType(primitiveType: PsiPrimitiveType): Type {
val name = primitiveType.canonicalText val name = primitiveType.canonicalText
return if (name == "void") { return when {
UnitType() name == "void" -> UnitType()
} PRIMITIVE_TYPES_NAMES.contains(name) -> PrimitiveType(Identifier.withNoPrototype(StringUtil.capitalize(name)))
else if (PRIMITIVE_TYPES_NAMES.contains(name)) { name == "null" -> NullType()
PrimitiveType(Identifier.withNoPrototype(StringUtil.capitalize(name))) else -> PrimitiveType(Identifier.withNoPrototype(name))
}
else if (name == "null") {
NullType()
}
else {
PrimitiveType(Identifier.withNoPrototype(name))
} }
} }
+4 -8
View File
@@ -27,20 +27,16 @@ fun quoteKeywords(packageName: String): String = packageName.split('.').joinToSt
fun getDefaultInitializer(property: Property): Expression? { fun getDefaultInitializer(property: Property): Expression? {
val t = property.type val t = property.type
val result = if (t.isNullable) { val result = when {
LiteralExpression("null") t.isNullable -> LiteralExpression("null")
} t is PrimitiveType -> when (t.name.name) {
else if (t is PrimitiveType) {
when (t.name.name) {
"Boolean" -> LiteralExpression("false") "Boolean" -> LiteralExpression("false")
"Char" -> LiteralExpression("' '") "Char" -> LiteralExpression("' '")
"Double" -> MethodCallExpression.buildNonNull(LiteralExpression("0").assignNoPrototype(), OperatorConventions.DOUBLE.toString()) "Double" -> MethodCallExpression.buildNonNull(LiteralExpression("0").assignNoPrototype(), OperatorConventions.DOUBLE.toString())
"Float" -> MethodCallExpression.buildNonNull(LiteralExpression("0").assignNoPrototype(), OperatorConventions.FLOAT.toString()) "Float" -> MethodCallExpression.buildNonNull(LiteralExpression("0").assignNoPrototype(), OperatorConventions.FLOAT.toString())
else -> LiteralExpression("0") else -> LiteralExpression("0")
} }
} else -> null
else {
null
} }
return result?.assignNoPrototype() return result?.assignNoPrototype()
} }
@@ -279,11 +279,10 @@ class ClassLiteralExpression(val type: Type): Expression() {
fun createArrayInitializerExpression(arrayType: ArrayType, initializers: List<Expression>, needExplicitType: Boolean = true) : MethodCallExpression { fun createArrayInitializerExpression(arrayType: ArrayType, initializers: List<Expression>, needExplicitType: Boolean = true) : MethodCallExpression {
val elementType = arrayType.elementType val elementType = arrayType.elementType
val createArrayFunction = if (elementType is PrimitiveType) val createArrayFunction = when {
(elementType.toNotNullType().canonicalCode() + "ArrayOf").decapitalize() elementType is PrimitiveType -> (elementType.toNotNullType().canonicalCode() + "ArrayOf").decapitalize()
else if (needExplicitType) needExplicitType -> "arrayOf<" + arrayType.elementType.canonicalCode() + ">"
"arrayOf<" + arrayType.elementType.canonicalCode() + ">" else -> "arrayOf"
else }
"arrayOf"
return MethodCallExpression.buildNonNull(null, createArrayFunction, ArgumentList.withNoPrototype(initializers)) return MethodCallExpression.buildNonNull(null, createArrayFunction, ArgumentList.withNoPrototype(initializers))
} }
@@ -387,14 +387,10 @@ private class PropertyDetector(
modifiers.add(Modifier.OVERRIDE) modifiers.add(Modifier.OVERRIDE)
} }
if (getMethod != null) { when {
modifiers.addIfNotNull(getterModifiers.accessModifier()) getMethod != null -> modifiers.addIfNotNull(getterModifiers.accessModifier())
} setMethod != null -> modifiers.addIfNotNull(getterModifiers.accessModifier())
else if (setMethod != null) { else -> modifiers.addIfNotNull(fieldModifiers.accessModifier())
modifiers.addIfNotNull(getterModifiers.accessModifier())
}
else {
modifiers.addIfNotNull(fieldModifiers.accessModifier())
} }
val prototypes = listOfNotNull<PsiElement>(field, getMethod, setMethod) val prototypes = listOfNotNull<PsiElement>(field, getMethod, setMethod)
@@ -432,16 +428,20 @@ private class PropertyDetector(
val superMethod = converter.services.superMethodsSearcher.findDeepestSuperMethods(getOrSetMethod).firstOrNull() ?: return null val superMethod = converter.services.superMethodsSearcher.findDeepestSuperMethods(getOrSetMethod).firstOrNull() ?: return null
val containingClass = superMethod.containingClass!! val containingClass = superMethod.containingClass!!
if (converter.inConversionScope(containingClass)) { return when {
converter.inConversionScope(containingClass) -> {
val propertyInfo = converter.propertyDetectionCache[containingClass][superMethod] val propertyInfo = converter.propertyDetectionCache[containingClass][superMethod]
return if (propertyInfo != null) SuperInfo.Property(propertyInfo.isVar, propertyInfo.name, propertyInfo.modifiers.contains(Modifier.ABSTRACT)) else SuperInfo.Function if (propertyInfo != null) SuperInfo.Property(propertyInfo.isVar, propertyInfo.name, propertyInfo.modifiers.contains(Modifier.ABSTRACT))
else SuperInfo.Function
} }
else if (superMethod is KtLightMethod) { superMethod is KtLightMethod -> {
val origin = superMethod.kotlinOrigin val origin = superMethod.kotlinOrigin
return if (origin is KtProperty) SuperInfo.Property(origin.isVar, origin.name ?: "", origin.hasModifier(KtTokens.ABSTRACT_KEYWORD)) else SuperInfo.Function if (origin is KtProperty) SuperInfo.Property(origin.isVar, origin.name ?: "", origin.hasModifier(KtTokens.ABSTRACT_KEYWORD))
else SuperInfo.Function
}
else -> {
SuperInfo.Function
} }
else {
return SuperInfo.Function
} }
} }
@@ -37,12 +37,11 @@ class FieldToPropertyProcessing(
if (field.name != propertyName || replaceReadWithFieldReference || replaceWriteWithFieldReference) MyConvertedCodeProcessor() else null if (field.name != propertyName || replaceReadWithFieldReference || replaceWriteWithFieldReference) MyConvertedCodeProcessor() else null
override var javaCodeProcessors = override var javaCodeProcessors =
if (field.hasModifierProperty(PsiModifier.PRIVATE)) when {
emptyList() field.hasModifierProperty(PsiModifier.PRIVATE) -> emptyList()
else if (field.name != propertyName) field.name != propertyName -> listOf(ElementRenamedCodeProcessor(propertyName), UseAccessorsJavaCodeProcessor())
listOf(ElementRenamedCodeProcessor(propertyName), UseAccessorsJavaCodeProcessor()) else -> listOf(UseAccessorsJavaCodeProcessor())
else }
listOf(UseAccessorsJavaCodeProcessor())
override val kotlinCodeProcessors = override val kotlinCodeProcessors =
if (field.name != propertyName) if (field.name != propertyName)
@@ -56,22 +56,19 @@ class Analyzer(private val context: Context) : JsVisitor() {
override fun visitExpressionStatement(x: JsExpressionStatement) { override fun visitExpressionStatement(x: JsExpressionStatement) {
val expression = x.expression val expression = x.expression
if (expression is JsBinaryOperation) { when (expression) {
if (expression.operator == JsBinaryOperator.ASG) { is JsBinaryOperation -> if (expression.operator == JsBinaryOperator.ASG) {
processAssignment(x, expression.arg1, expression.arg2)?.let { processAssignment(x, expression.arg1, expression.arg2)?.let {
// Mark this statement with FQN extracted from assignment. // Mark this statement with FQN extracted from assignment.
// Later, we eliminate such statements if corresponding FQN is reachable // Later, we eliminate such statements if corresponding FQN is reachable
nodeMap[x] = it nodeMap[x] = it
} }
} }
} is JsFunction -> expression.name?.let { context.nodes[it]?.original }?.let {
else if (expression is JsFunction) {
expression.name?.let { context.nodes[it]?.original }?.let {
nodeMap[x] = it nodeMap[x] = it
it.functions += expression it.functions += expression
} }
} is JsInvocation -> {
else if (expression is JsInvocation) {
val function = expression.qualifier val function = expression.qualifier
// (function(params) { ... })(arguments), assume that params = arguments and walk its body // (function(params) { ... })(arguments), assume that params = arguments and walk its body
@@ -91,22 +88,21 @@ class Analyzer(private val context: Context) : JsVisitor() {
} }
// Object.defineProperty() // Object.defineProperty()
if (context.isObjectDefineProperty(function)) { when {
context.isObjectDefineProperty(function) ->
handleObjectDefineProperty(x, expression.arguments.getOrNull(0), expression.arguments.getOrNull(1), handleObjectDefineProperty(x, expression.arguments.getOrNull(0), expression.arguments.getOrNull(1),
expression.arguments.getOrNull(2)) expression.arguments.getOrNull(2))
}
// Kotlin.defineModule() // Kotlin.defineModule()
else if (context.isDefineModule(function)) { context.isDefineModule(function) ->
// (just remove it) // (just remove it)
astNodesToEliminate += x astNodesToEliminate += x
} context.isAmdDefine(function) ->
else if (context.isAmdDefine(function)) {
handleAmdDefine(expression, expression.arguments) handleAmdDefine(expression, expression.arguments)
} }
} }
} }
}
private fun handleObjectDefineProperty(statement: JsStatement, target: JsExpression?, propertyName: JsExpression?, private fun handleObjectDefineProperty(statement: JsStatement, target: JsExpression?, propertyName: JsExpression?,
propertyDescriptor: JsExpression?) { propertyDescriptor: JsExpression?) {
@@ -201,7 +197,8 @@ class Analyzer(private val context: Context) : JsVisitor() {
} }
else if (leftNode != null) { else if (leftNode != null) {
// lhs = foo() // lhs = foo()
if (rhs is JsInvocation) { when {
rhs is JsInvocation -> {
val function = rhs.qualifier val function = rhs.qualifier
// lhs = function(params) { ... }(arguments) // lhs = function(params) { ... }(arguments)
@@ -240,8 +237,7 @@ class Analyzer(private val context: Context) : JsVisitor() {
return leftNode return leftNode
} }
} }
else if (rhs is JsBinaryOperation) { rhs is JsBinaryOperation -> // Detect lhs = parent.child || (parent.child = {}), which is used to declare packages.
// Detect lhs = parent.child || (parent.child = {}), which is used to declare packages.
// Assume lhs = parent.child // Assume lhs = parent.child
if (rhs.operator == JsBinaryOperator.OR) { if (rhs.operator == JsBinaryOperator.OR) {
val secondNode = context.extractNode(rhs.arg1) val secondNode = context.extractNode(rhs.arg1)
@@ -256,22 +252,20 @@ class Analyzer(private val context: Context) : JsVisitor() {
} }
} }
} }
} rhs is JsFunction -> {
else if (rhs is JsFunction) {
// lhs = function() { ... } // lhs = function() { ... }
// During reachability tracking phase: eliminate it if lhs is unreachable, traverse function otherwise // During reachability tracking phase: eliminate it if lhs is unreachable, traverse function otherwise
leftNode.functions += rhs leftNode.functions += rhs
return leftNode return leftNode
} }
else if (leftNode.qualifier?.memberName == Namer.METADATA) { leftNode.qualifier?.memberName == Namer.METADATA -> {
// lhs.$metadata$ = expression // lhs.$metadata$ = expression
// During reachability tracking phase: eliminate it if lhs is unreachable, traverse expression // During reachability tracking phase: eliminate it if lhs is unreachable, traverse expression
// It's commonly used to supply class's metadata // It's commonly used to supply class's metadata
leftNode.expressions += rhs leftNode.expressions += rhs
return leftNode return leftNode
} }
else if (rhs is JsObjectLiteral && rhs.propertyInitializers.isEmpty()) { rhs is JsObjectLiteral && rhs.propertyInitializers.isEmpty() -> return leftNode
return leftNode
} }
val nodeInitializedByEmptyObject = extractVariableInitializedByEmptyObject(rhs) val nodeInitializedByEmptyObject = extractVariableInitializedByEmptyObject(rhs)
@@ -222,15 +222,13 @@ object JsExternalChecker : SimpleDeclarationChecker {
private fun KtDeclarationWithBody.hasValidExternalBody(bindingContext: BindingContext): Boolean { private fun KtDeclarationWithBody.hasValidExternalBody(bindingContext: BindingContext): Boolean {
if (!hasBody()) return true if (!hasBody()) return true
val body = bodyExpression!! val body = bodyExpression!!
return if (!hasBlockBody()) { return when {
body.isDefinedExternallyExpression(bindingContext) !hasBlockBody() -> body.isDefinedExternallyExpression(bindingContext)
} body is KtBlockExpression -> {
else if (body is KtBlockExpression) {
val statement = body.statements.singleOrNull() ?: return false val statement = body.statements.singleOrNull() ?: return false
statement.isDefinedExternallyExpression(bindingContext) statement.isDefinedExternallyExpression(bindingContext)
} }
else { else -> false
false
} }
} }
@@ -66,17 +66,19 @@ class RedundantStatementElimination(private val root: JsFunction) {
private fun replace(expression: JsExpression): List<JsExpression> { private fun replace(expression: JsExpression): List<JsExpression> {
return when (expression) { return when (expression) {
is JsNameRef -> { is JsNameRef -> {
if (expression.name in localVars) { when {
expression.name in localVars -> {
listOf() listOf()
} }
else if (expression.sideEffects != SideEffectKind.AFFECTS_STATE) { expression.sideEffects != SideEffectKind.AFFECTS_STATE -> {
val qualifier = expression.qualifier val qualifier = expression.qualifier
if (qualifier != null) replace(qualifier) else listOf() if (qualifier != null) replace(qualifier) else listOf()
} }
else { else -> {
listOf(expression) listOf(expression)
} }
} }
}
is JsUnaryOperation -> { is JsUnaryOperation -> {
when (expression.operator!!) { when (expression.operator!!) {
@@ -190,26 +190,19 @@ object Constants {
private fun formatChar(c: Char) = '\'' + quote(c) + '\'' private fun formatChar(c: Char) = '\'' + quote(c) + '\''
private fun formatString(s: String) = '"' + quote(s) + '"' private fun formatString(s: String) = '"' + quote(s) + '"'
private fun formatFloat(f: Float): String { private fun formatFloat(f: Float): String = when {
if (java.lang.Float.isNaN(f)) java.lang.Float.isNaN(f) -> "0.0f/0.0f"
return "0.0f/0.0f" java.lang.Float.isInfinite(f) -> if (f < 0) "-1.0f/0.0f" else "1.0f/0.0f"
else if (java.lang.Float.isInfinite(f)) else -> "${f}f"
return if (f < 0) "-1.0f/0.0f" else "1.0f/0.0f"
else
return "${f}f"
} }
private fun formatDouble(d: Double): String { private fun formatDouble(d: Double): String = when {
if (java.lang.Double.isNaN(d)) java.lang.Double.isNaN(d) -> "0.0/0.0"
return "0.0/0.0" java.lang.Double.isInfinite(d) -> if (d < 0) "-1.0/0.0" else "1.0/0.0"
else if (java.lang.Double.isInfinite(d)) else -> d.toString()
return if (d < 0) "-1.0/0.0" else "1.0/0.0"
else
return d.toString()
} }
fun quote(ch: Char): String { fun quote(ch: Char): String = when (ch) {
return when (ch) {
'\b' -> "\\b" '\b' -> "\\b"
'\n' -> "\\n" '\n' -> "\\n"
'\r' -> "\\r" '\r' -> "\\r"
@@ -219,7 +212,6 @@ object Constants {
'\\' -> "\\\\" '\\' -> "\\\\"
else -> if (isPrintableAscii(ch)) ch.toString() else String.format("\\u%04x", ch.toInt()) else -> if (isPrintableAscii(ch)) ch.toString() else String.format("\\u%04x", ch.toInt())
} }
}
fun quote(s: String): String { fun quote(s: String): String {
val buf = StringBuilder() val buf = StringBuilder()
@@ -95,12 +95,10 @@ class KotlinTypes(
if (extendsBound != null && extendsBound !is JePsiType) illegalArg("extendsBound should have PsiType") if (extendsBound != null && extendsBound !is JePsiType) illegalArg("extendsBound should have PsiType")
if (superBound != null && superBound !is JePsiType) illegalArg("superBound should have PsiType") if (superBound != null && superBound !is JePsiType) illegalArg("superBound should have PsiType")
return JeWildcardType(if (extendsBound != null) { return JeWildcardType(when {
PsiWildcardType.createExtends(psiManager(), (extendsBound as JePsiType).psiType) extendsBound != null -> PsiWildcardType.createExtends(psiManager(), (extendsBound as JePsiType).psiType)
} else if (superBound != null) { superBound != null -> PsiWildcardType.createSuper(psiManager(), (superBound as JePsiType).psiType)
PsiWildcardType.createSuper(psiManager(), (superBound as JePsiType).psiType) else -> PsiWildcardType.createUnbounded(psiManager())
} else {
PsiWildcardType.createUnbounded(psiManager())
}, isRaw = false) }, isRaw = false)
} }
@@ -80,15 +80,12 @@ class SuppressLintIntentionAction(val id: String, val element: PsiElement) : Int
val args = entry.valueArgumentList val args = entry.valueArgumentList
val psiFactory = KtPsiFactory(entry) val psiFactory = KtPsiFactory(entry)
val newArgList = psiFactory.createCallArguments("($argument)") val newArgList = psiFactory.createCallArguments("($argument)")
if (args == null) { when {
// new argument list args == null -> // new argument list
entry.addAfter(newArgList, entry.lastChild) entry.addAfter(newArgList, entry.lastChild)
} args.arguments.isEmpty() -> // replace '()' with a new argument list
else if (args.arguments.isEmpty()) {
// replace '()' with a new argument list
args.replace(newArgList) args.replace(newArgList)
} args.arguments.none { it.textMatches(argument) } ->
else if (args.arguments.none { it.textMatches(argument) }) {
args.addArgument(newArgList.arguments[0]) args.addArgument(newArgList.arguments[0])
} }
@@ -286,17 +286,18 @@ internal object KotlinConverter {
is KtVariableDeclaration -> expr<UDeclarationsExpression>(build(::convertVariablesDeclaration)) is KtVariableDeclaration -> expr<UDeclarationsExpression>(build(::convertVariablesDeclaration))
is KtStringTemplateExpression -> { is KtStringTemplateExpression -> {
if (expression.entries.isEmpty()) { when {
expression.entries.isEmpty() -> {
val parent = if (parentCallback == null) null else (parentCallback() ?: return null) val parent = if (parentCallback == null) null else (parentCallback() ?: return null)
expr<ULiteralExpression> { KotlinStringULiteralExpression(expression, parent, "") } expr<ULiteralExpression> { KotlinStringULiteralExpression(expression, parent, "") }
} }
else if (expression.entries.size == 1) expression.entries.size == 1 -> convertEntry(expression.entries[0], parentCallback, requiredType)
convertEntry(expression.entries[0], parentCallback, requiredType) else -> {
else {
val parent = if (parentCallback == null) null else (parentCallback() ?: return null) val parent = if (parentCallback == null) null else (parentCallback() ?: return null)
expr<UExpression> { KotlinStringTemplateUPolyadicExpression(expression, parent) } expr<UExpression> { KotlinStringTemplateUPolyadicExpression(expression, parent) }
} }
} }
}
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> { is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
val parent = if (parentCallback == null) null else (parentCallback() ?: return null) val parent = if (parentCallback == null) null else (parentCallback() ?: return null)
KotlinUDeclarationsExpression(parent).apply { KotlinUDeclarationsExpression(parent).apply {