Code cleanup: unnecessary local variable applied

This commit is contained in:
Mikhail Glukhikh
2017-07-20 16:10:35 +03:00
parent 202fb19cf6
commit 951e8cd91a
57 changed files with 118 additions and 203 deletions
@@ -94,8 +94,7 @@ class JvmStaticInCompanionObjectGenerator(
CallableMemberDescriptor.Kind.SYNTHESIZED, CallableMemberDescriptor.Kind.SYNTHESIZED,
false false
) )
val staticFunctionDescriptor = copies[descriptor]!! return copies[descriptor]!!
return staticFunctionDescriptor
} }
} }
} }
@@ -111,12 +111,11 @@ class CoroutineTransformerMethodVisitor(
methodNode.instructions.apply { methodNode.instructions.apply {
val startLabel = LabelNode() val startLabel = LabelNode()
val defaultLabel = LabelNode() val defaultLabel = LabelNode()
val firstToInsertBefore = actualCoroutineStart
val tableSwitchLabel = LabelNode() val tableSwitchLabel = LabelNode()
val lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0 val lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0
// tableswitch(this.label) // tableswitch(this.label)
insertBefore(firstToInsertBefore, insertBefore(actualCoroutineStart,
insnListOf( insnListOf(
*withInstructionAdapter { loadCoroutineSuspendedMarker() }.toArray(), *withInstructionAdapter { loadCoroutineSuspendedMarker() }.toArray(),
tableSwitchLabel, tableSwitchLabel,
@@ -144,7 +144,7 @@ internal fun performRefinedTypeAnalysis(methodNode: MethodNode, thisName: String
} }
}) })
val refinedFrames = Array(basicFrames.size) { return Array(basicFrames.size) {
insnIndex -> insnIndex ->
val current = Frame(basicFrames[insnIndex] ?: return@Array null) val current = Frame(basicFrames[insnIndex] ?: return@Array null)
@@ -158,8 +158,6 @@ internal fun performRefinedTypeAnalysis(methodNode: MethodNode, thisName: String
current current
} }
return refinedFrames
} }
private fun AbstractInsnNode.isIntLoad() = opcode == Opcodes.ILOAD private fun AbstractInsnNode.isIntLoad() = opcode == Opcodes.ILOAD
@@ -716,10 +716,9 @@ class MethodInliner(
"Captured field template should start with $CAPTURED_FIELD_FOLD_PREFIX prefix" "Captured field template should start with $CAPTURED_FIELD_FOLD_PREFIX prefix"
} }
val fin = FieldInsnNode(node.opcode, node.owner, node.name.substring(3), node.desc) val fin = FieldInsnNode(node.opcode, node.owner, node.name.substring(3), node.desc)
val field = fieldRemapper.findField(fin) ?: throw IllegalStateException( return fieldRemapper.findField(fin) ?: throw IllegalStateException(
"Couldn't find captured field ${node.owner}.${node.name} in ${fieldRemapper.originalLambdaInternalName}" "Couldn't find captured field ${node.owner}.${node.name} in ${fieldRemapper.originalLambdaInternalName}"
) )
return field
} }
private fun analyzeMethodNodeWithoutMandatoryTransformations(node: MethodNode): Array<Frame<SourceValue>?> { private fun analyzeMethodNodeWithoutMandatoryTransformations(node: MethodNode): Array<Frame<SourceValue>?> {
@@ -169,8 +169,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
val strategy = when (expression) { val strategy = when (expression) {
is KtCallableReferenceExpression -> { is KtCallableReferenceExpression -> {
val callableReferenceExpression = expression val receiverExpression = expression.receiverExpression
val receiverExpression = callableReferenceExpression.receiverExpression
val receiverType = if (receiverExpression != null && state.bindingContext.getType(receiverExpression) != null) val receiverType = if (receiverExpression != null && state.bindingContext.getType(receiverExpression) != null)
state.typeMapper.mapType(state.bindingContext.getType(receiverExpression)!!) state.typeMapper.mapType(state.bindingContext.getType(receiverExpression)!!)
else else
@@ -187,7 +186,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
FunctionReferenceGenerationStrategy( FunctionReferenceGenerationStrategy(
state, state,
descriptor, descriptor,
callableReferenceExpression.callableReference expression.callableReference
.getResolvedCallWithAssert(state.bindingContext), .getResolvedCallWithAssert(state.bindingContext),
receiverType, null, receiverType, null,
true true
@@ -286,9 +286,8 @@ internal fun getMarkedReturnLabelOrNull(returnInsn: AbstractInsnNode): String? {
} }
val previous = returnInsn.previous val previous = returnInsn.previous
if (previous is MethodInsnNode) { if (previous is MethodInsnNode) {
val marker = previous if (NON_LOCAL_RETURN == previous.owner) {
if (NON_LOCAL_RETURN == marker.owner) { return previous.name
return marker.name
} }
} }
return null return null
@@ -457,13 +456,12 @@ private fun isInlineMarker(insn: AbstractInsnNode, name: String?): Boolean {
return false return false
} }
val methodInsnNode = insn
return insn.getOpcode() == Opcodes.INVOKESTATIC && return insn.getOpcode() == Opcodes.INVOKESTATIC &&
methodInsnNode.owner == INLINE_MARKER_CLASS_NAME && insn.owner == INLINE_MARKER_CLASS_NAME &&
if (name != null) if (name != null)
methodInsnNode.name == name insn.name == name
else else
methodInsnNode.name == INLINE_MARKER_BEFORE_METHOD_NAME || methodInsnNode.name == INLINE_MARKER_AFTER_METHOD_NAME insn.name == INLINE_MARKER_BEFORE_METHOD_NAME || insn.name == INLINE_MARKER_AFTER_METHOD_NAME
} }
internal fun isBeforeInlineMarker(insn: AbstractInsnNode): Boolean { internal fun isBeforeInlineMarker(insn: AbstractInsnNode): Boolean {
@@ -232,17 +232,15 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
} }
private fun findCleanInstructions(refValue: CapturedVarDescriptor, oldVarIndex: Int, instructions: InsnList): List<VarInsnNode> { private fun findCleanInstructions(refValue: CapturedVarDescriptor, oldVarIndex: Int, instructions: InsnList): List<VarInsnNode> {
val cleanInstructions = return InsnSequence(instructions).filterIsInstance<VarInsnNode>().filter {
InsnSequence(instructions).filterIsInstance<VarInsnNode>().filter { it.opcode == Opcodes.ASTORE && it.`var` == oldVarIndex
it.opcode == Opcodes.ASTORE && it.`var` == oldVarIndex }.filter {
}.filter { it.previous?.opcode == Opcodes.ACONST_NULL
it.previous?.opcode == Opcodes.ACONST_NULL }.filter {
}.filter { val operationIndex = instructions.indexOf(it)
val operationIndex = instructions.indexOf(it) val localVariableNode = refValue.localVar!!
val localVariableNode = refValue.localVar!! instructions.indexOf(localVariableNode.start) < operationIndex && operationIndex < instructions.indexOf(localVariableNode.end)
instructions.indexOf(localVariableNode.start) < operationIndex && operationIndex < instructions.indexOf(localVariableNode.end) }.toList()
}.toList()
return cleanInstructions
} }
private fun rewrite() { private fun rewrite() {
@@ -59,14 +59,13 @@ abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEn
val codeLine = nextCodeLine(context, script) val codeLine = nextCodeLine(context, script)
val state = getCurrentState(context) val state = getCurrentState(context)
val result = replEvaluator.compileAndEval(state, codeLine, scriptArgs = overrideScriptArgs(context)) val result = replEvaluator.compileAndEval(state, codeLine, scriptArgs = overrideScriptArgs(context))
val ret = when (result) { return when (result) {
is ReplEvalResult.ValueResult -> result.value is ReplEvalResult.ValueResult -> result.value
is ReplEvalResult.UnitResult -> null is ReplEvalResult.UnitResult -> null
is ReplEvalResult.Error -> throw ScriptException(result.message) is ReplEvalResult.Error -> throw ScriptException(result.message)
is ReplEvalResult.Incomplete -> throw ScriptException("error: incomplete code") is ReplEvalResult.Incomplete -> throw ScriptException("error: incomplete code")
is ReplEvalResult.HistoryMismatch -> throw ScriptException("Repl history mismatch at line: ${result.lineNo}") is ReplEvalResult.HistoryMismatch -> throw ScriptException("Repl history mismatch at line: ${result.lineNo}")
} }
return ret
} }
open fun compile(script: String, context: ScriptContext): CompiledScript { open fun compile(script: String, context: ScriptContext): CompiledScript {
@@ -91,14 +90,13 @@ abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEn
throw ScriptException(e) throw ScriptException(e)
} }
val ret = when (result) { return when (result) {
is ReplEvalResult.ValueResult -> result.value is ReplEvalResult.ValueResult -> result.value
is ReplEvalResult.UnitResult -> null is ReplEvalResult.UnitResult -> null
is ReplEvalResult.Error -> throw ScriptException(result.message) is ReplEvalResult.Error -> throw ScriptException(result.message)
is ReplEvalResult.Incomplete -> throw ScriptException("error: incomplete code") is ReplEvalResult.Incomplete -> throw ScriptException("error: incomplete code")
is ReplEvalResult.HistoryMismatch -> throw ScriptException("Repl history mismatch at line: ${result.lineNo}") is ReplEvalResult.HistoryMismatch -> throw ScriptException("Repl history mismatch at line: ${result.lineNo}")
} }
return ret
} }
class CompiledKotlinScript(val engine: KotlinJsr223JvmScriptEngineBase, val codeLine: ReplCodeLine, val compiledData: ReplCompileResult.CompiledClasses) : CompiledScript() { class CompiledKotlinScript(val engine: KotlinJsr223JvmScriptEngineBase, val codeLine: ReplCodeLine, val compiledData: ReplCompileResult.CompiledClasses) : CompiledScript() {
@@ -44,8 +44,7 @@ class KtNameReferenceExpression : KtExpressionImplStub<KotlinNameReferenceExpres
} }
override fun getReferencedNameElement(): PsiElement { override fun getReferencedNameElement(): PsiElement {
val element = findChildByType<PsiElement>(NAME_REFERENCE_EXPRESSIONS) ?: return this return findChildByType(NAME_REFERENCE_EXPRESSIONS) ?: this
return element
} }
override fun getIdentifier(): PsiElement? { override fun getIdentifier(): PsiElement? {
@@ -274,9 +274,7 @@ class KtPsiFactory @JvmOverloads constructor(private val project: Project, val m
val file = createFile(text) val file = createFile(text)
val declarations = file.declarations val declarations = file.declarations
assert(declarations.size == 1) { "${declarations.size} declarations in $text" } assert(declarations.size == 1) { "${declarations.size} declarations in $text" }
@Suppress("UNCHECKED_CAST") return declarations.first() as TDeclaration
val result = declarations.first() as TDeclaration
return result
} }
fun createNameIdentifier(name: String): PsiElement { fun createNameIdentifier(name: String): PsiElement {
@@ -108,11 +108,10 @@ fun KtSimpleNameExpression.getReceiverExpression(): KtExpression? {
} }
parent is KtCallExpression -> { parent is KtCallExpression -> {
//This is in case `a().b()` //This is in case `a().b()`
val callExpression = parent val grandParent = parent.parent
val grandParent = callExpression.parent
if (grandParent is KtQualifiedExpression) { if (grandParent is KtQualifiedExpression) {
val parentsReceiver = grandParent.receiverExpression val parentsReceiver = grandParent.receiverExpression
if (parentsReceiver != callExpression) { if (parentsReceiver != parent) {
return parentsReceiver return parentsReceiver
} }
} }
@@ -44,7 +44,6 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
import java.util.* import java.util.*
import kotlin.collections.HashMap
class KotlinToResolvedCallTransformer( class KotlinToResolvedCallTransformer(
@@ -112,7 +111,7 @@ class KotlinToResolvedCallTransformer(
return this return this
} }
val resolvedCall = when (completedCall) { return when (completedCall) {
is CompletedKotlinCall.Simple -> { is CompletedKotlinCall.Simple -> {
NewResolvedCallImpl<D>(completedCall).runIfTraceNotNull(this::bindResolvedCall).runIfTraceNotNull(this::runArgumentsChecks) NewResolvedCallImpl<D>(completedCall).runIfTraceNotNull(this::bindResolvedCall).runIfTraceNotNull(this::runArgumentsChecks)
} }
@@ -127,8 +126,6 @@ class KotlinToResolvedCallTransformer(
(resolvedCall as ResolvedCall<D>) (resolvedCall as ResolvedCall<D>)
} }
} }
return resolvedCall
} }
private fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) { private fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) {
@@ -333,8 +330,7 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>(): ResolvedCall<D>
if (argumentToParameterMap == null) { if (argumentToParameterMap == null) {
argumentToParameterMap = argumentToParameterMap(resultingDescriptor, valueArguments) argumentToParameterMap = argumentToParameterMap(resultingDescriptor, valueArguments)
} }
val argumentMatch = argumentToParameterMap!![valueArgument] ?: return ArgumentUnmapped return argumentToParameterMap!![valueArgument] ?: ArgumentUnmapped
return argumentMatch
} }
override fun getDataFlowInfoForArguments() = object : DataFlowInfoForArguments { override fun getDataFlowInfoForArguments() = object : DataFlowInfoForArguments {
@@ -463,11 +463,10 @@ class PSICallResolver(
val newDataFlowInfo = (lhsResult as? DoubleColonLHS.Expression)?.dataFlowInfo ?: startDataFlowInfo val newDataFlowInfo = (lhsResult as? DoubleColonLHS.Expression)?.dataFlowInfo ?: startDataFlowInfo
// todo ChosenCallableReferenceDescriptor // todo ChosenCallableReferenceDescriptor
val argument = CallableReferenceKotlinCallArgumentImpl(valueArgument, startDataFlowInfo, newDataFlowInfo,
ktExpression, argumentName, (lhsResult as? DoubleColonLHS.Type)?.type?.unwrap(),
ConstraintStorage.Empty) // todo
return argument return CallableReferenceKotlinCallArgumentImpl(valueArgument, startDataFlowInfo, newDataFlowInfo,
ktExpression, argumentName, (lhsResult as? DoubleColonLHS.Type)?.type?.unwrap(),
ConstraintStorage.Empty)
} }
// valueArgument.getArgumentExpression()!! instead of ktExpression is hack -- type info should be stored also for parenthesized expression // valueArgument.getArgumentExpression()!! instead of ktExpression is hack -- type info should be stored also for parenthesized expression
@@ -161,10 +161,9 @@ class PatternMatchingTypingVisitor internal constructor(facade: ExpressionTyping
private fun wrapWhenEntryExpressionsAsSpecialCallArguments(expression: KtWhenExpression): List<KtExpression> { private fun wrapWhenEntryExpressionsAsSpecialCallArguments(expression: KtWhenExpression): List<KtExpression> {
val psiFactory = KtPsiFactory(expression) val psiFactory = KtPsiFactory(expression)
val wrappedArgumentExpressions = expression.entries.mapNotNull { whenEntry -> return expression.entries.mapNotNull { whenEntry ->
whenEntry.expression?.let { psiFactory.wrapInABlockWrapper(it) } whenEntry.expression?.let { psiFactory.wrapInABlockWrapper(it) }
} }
return wrappedArgumentExpressions
} }
private fun analyzeConditionsInWhenEntries( private fun analyzeConditionsInWhenEntries(
@@ -126,9 +126,7 @@ class LocalFunctionsLowering(val context: BackendContext): DeclarationContainerL
val newCallee = localFunctionData.transformedDescriptor val newCallee = localFunctionData.transformedDescriptor
val newCall = createNewCall(expression, newCallee).fillArguments(localFunctionData, expression) return createNewCall(expression, newCallee).fillArguments(localFunctionData, expression)
return newCall
} }
private fun <T : IrMemberAccessExpression> T.fillArguments(calleeContext: LocalFunctionContext, oldExpression: IrMemberAccessExpression): T { private fun <T : IrMemberAccessExpression> T.fillArguments(calleeContext: LocalFunctionContext, oldExpression: IrMemberAccessExpression): T {
@@ -160,15 +158,13 @@ class LocalFunctionsLowering(val context: BackendContext): DeclarationContainerL
val localFunctionData = localFunctions[oldCallee] ?: return expression val localFunctionData = localFunctions[oldCallee] ?: return expression
val newCallee = localFunctionData.transformedDescriptor val newCallee = localFunctionData.transformedDescriptor
val newCallableReference = IrFunctionReferenceImpl( return IrFunctionReferenceImpl(
expression.startOffset, expression.endOffset, expression.startOffset, expression.endOffset,
expression.type, // TODO functional type for transformed descriptor expression.type, // TODO functional type for transformed descriptor
newCallee, newCallee,
remapTypeArguments(expression, newCallee), remapTypeArguments(expression, newCallee),
expression.origin expression.origin
).fillArguments(localFunctionData, expression) ).fillArguments(localFunctionData, expression)
return newCallableReference
} }
override fun visitReturn(expression: IrReturn): IrExpression { override fun visitReturn(expression: IrReturn): IrExpression {
@@ -341,10 +341,9 @@ class ExpressionCodegen(
} }
private fun findLocalIndex(descriptor: CallableDescriptor): Int { private fun findLocalIndex(descriptor: CallableDescriptor): Int {
val index = frame.getIndex(descriptor).apply { return frame.getIndex(descriptor).apply {
if (this < 0) throw AssertionError("Non-mapped local variable descriptor: $descriptor") if (this < 0) throw AssertionError("Non-mapped local variable descriptor: $descriptor")
} }
return index
} }
override fun visitGetObjectValue(expression: IrGetObjectValue, data: BlockInfo): StackValue { override fun visitGetObjectValue(expression: IrGetObjectValue, data: BlockInfo): StackValue {
@@ -453,13 +452,12 @@ class ExpressionCodegen(
} }
else { else {
mv.iconst(size) mv.iconst(size)
val asmType = elementType
newArrayInstruction(expression.type) newArrayInstruction(expression.type)
for ((i, element) in expression.elements.withIndex()) { for ((i, element) in expression.elements.withIndex()) {
mv.dup() mv.dup()
StackValue.constant(i, Type.INT_TYPE).put(Type.INT_TYPE, mv) StackValue.constant(i, Type.INT_TYPE).put(Type.INT_TYPE, mv)
val rightSide = gen(element, asmType, data) val rightSide = gen(element, elementType, data)
StackValue.arrayElement(asmType, StackValue.onStack(asmType), StackValue.onStack(Type.INT_TYPE)).store(rightSide, mv) StackValue.arrayElement(elementType, StackValue.onStack(elementType), StackValue.onStack(Type.INT_TYPE)).store(rightSide, mv)
} }
} }
return expression.onStack return expression.onStack
@@ -125,14 +125,12 @@ class SpecialDescriptorsFactory(
private fun createObjectInstanceFieldDescriptor(objectDescriptor: ClassDescriptor): PropertyDescriptor { private fun createObjectInstanceFieldDescriptor(objectDescriptor: ClassDescriptor): PropertyDescriptor {
assert(objectDescriptor.kind == ClassKind.OBJECT) { "Should be an object: $objectDescriptor" } assert(objectDescriptor.kind == ClassKind.OBJECT) { "Should be an object: $objectDescriptor" }
val instanceFieldDescriptor = PropertyDescriptorImpl.create( return PropertyDescriptorImpl.create(
objectDescriptor, objectDescriptor,
Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false, Annotations.EMPTY, Modality.FINAL, Visibilities.PUBLIC, false,
Name.identifier("INSTANCE"), Name.identifier("INSTANCE"),
CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false, CallableMemberDescriptor.Kind.SYNTHESIZED, SourceElement.NO_SOURCE, /* lateInit = */ false, /* isConst = */ false,
/* isHeader = */ false, /* isImpl = */ false, /* isExternal = */ false, /* isDelegated = */ false /* isHeader = */ false, /* isImpl = */ false, /* isExternal = */ false, /* isDelegated = */ false
).initialize(objectDescriptor.defaultType) ).initialize(objectDescriptor.defaultType)
return instanceFieldDescriptor
} }
} }
@@ -99,11 +99,10 @@ open class IrIntrinsicFunction(
fun IrMemberAccessExpression.argTypes(context: JvmBackendContext): ArrayList<Type> { fun IrMemberAccessExpression.argTypes(context: JvmBackendContext): ArrayList<Type> {
val callableMethod = context.state.typeMapper.mapToCallableMethod(descriptor as FunctionDescriptor, false) val callableMethod = context.state.typeMapper.mapToCallableMethod(descriptor as FunctionDescriptor, false)
val args = arrayListOf<Type>().apply { return arrayListOf<Type>().apply {
callableMethod.dispatchReceiverType?.let { add(it) } callableMethod.dispatchReceiverType?.let { add(it) }
addAll(callableMethod.getAsmMethod().argumentTypes) addAll(callableMethod.getAsmMethod().argumentTypes)
} }
return args
} }
fun IrMemberAccessExpression.receiverAndArgs(): List<IrExpression> { fun IrMemberAccessExpression.receiverAndArgs(): List<IrExpression> {
@@ -117,12 +117,11 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
private fun transformEnumConstructor(enumConstructor: IrConstructor): IrConstructor { private fun transformEnumConstructor(enumConstructor: IrConstructor): IrConstructor {
val constructorDescriptor = enumConstructor.descriptor val constructorDescriptor = enumConstructor.descriptor
val loweredConstructorDescriptor = lowerEnumConstructor(constructorDescriptor) val loweredConstructorDescriptor = lowerEnumConstructor(constructorDescriptor)
val loweredEnumConstructor = IrConstructorImpl( return IrConstructorImpl(
enumConstructor.startOffset, enumConstructor.endOffset, enumConstructor.origin, enumConstructor.startOffset, enumConstructor.endOffset, enumConstructor.origin,
loweredConstructorDescriptor, loweredConstructorDescriptor,
enumConstructor.body!! // will be transformed later enumConstructor.body!! // will be transformed later
) )
return loweredEnumConstructor
} }
private fun lowerEnumConstructor(constructorDescriptor: ClassConstructorDescriptor): ClassConstructorDescriptor { private fun lowerEnumConstructor(constructorDescriptor: ClassConstructorDescriptor): ClassConstructorDescriptor {
@@ -221,10 +220,9 @@ class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
val irValuesInitializer = createSyntheticValuesFieldInitializerExpression() val irValuesInitializer = createSyntheticValuesFieldInitializerExpression()
val irField = IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_VALUES, return IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, JvmLoweredDeclarationOrigin.FIELD_FOR_ENUM_VALUES,
valuesFieldDescriptor, valuesFieldDescriptor,
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValuesInitializer)) IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, irValuesInitializer))
return irField
} }
private fun createSyntheticValuesFieldInitializerExpression(): IrExpression = private fun createSyntheticValuesFieldInitializerExpression(): IrExpression =
@@ -173,13 +173,12 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
private fun generateReceiverExpressionForDefaultPropertyAccessor(ktProperty: KtElement, property: PropertyDescriptor): IrExpression? { private fun generateReceiverExpressionForDefaultPropertyAccessor(ktProperty: KtElement, property: PropertyDescriptor): IrExpression? {
val containingDeclaration = property.containingDeclaration val containingDeclaration = property.containingDeclaration
val receiver = when (containingDeclaration) { return when (containingDeclaration) {
is ClassDescriptor -> is ClassDescriptor ->
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset,
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter)) context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter))
else -> null else -> null
} }
return receiver
} }
fun generatePrimaryConstructor( fun generatePrimaryConstructor(
@@ -129,7 +129,6 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
private fun getPropertyDescriptor(ktProperty: KtProperty): PropertyDescriptor { private fun getPropertyDescriptor(ktProperty: KtProperty): PropertyDescriptor {
val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty) val variableDescriptor = getOrFail(BindingContext.VARIABLE, ktProperty)
val propertyDescriptor = variableDescriptor as? PropertyDescriptor ?: TODO("not a property?") return variableDescriptor as? PropertyDescriptor ?: TODO("not a property?")
return propertyDescriptor
} }
} }
@@ -43,8 +43,7 @@ class SymbolTable {
unboundSymbols.remove(existing) unboundSymbols.remove(existing)
existing existing
} }
val owner = createOwner(symbol) return createOwner(symbol)
return owner
} }
inline fun referenced(d: D, createSymbol: () -> S): S { inline fun referenced(d: D, createSymbol: () -> S): S {
@@ -115,8 +114,7 @@ class SymbolTable {
inline fun declareLocal(d: D, createSymbol: () -> S, createOwner: (S) -> B): B { inline fun declareLocal(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
val scope = currentScope ?: throw AssertionError("No active scope") val scope = currentScope ?: throw AssertionError("No active scope")
val symbol = scope.getLocal(d) ?: createSymbol().also { scope[d] = it } val symbol = scope.getLocal(d) ?: createSymbol().also { scope[d] = it }
val owner = createOwner(symbol) return createOwner(symbol)
return owner
} }
fun introduceLocal(descriptor: D, symbol: S) { fun introduceLocal(descriptor: D, symbol: S) {
@@ -116,9 +116,8 @@ object NewKotlinTypeChecker : KotlinTypeChecker {
if (constructor.newTypeConstructor == null) { if (constructor.newTypeConstructor == null) {
constructor.newTypeConstructor = NewCapturedTypeConstructor(constructor.typeProjection, constructor.supertypes.map { it.unwrap() }) constructor.newTypeConstructor = NewCapturedTypeConstructor(constructor.typeProjection, constructor.supertypes.map { it.unwrap() })
} }
val newCapturedType = NewCapturedType(CaptureStatus.FOR_SUBTYPING, constructor.newTypeConstructor!!, return NewCapturedType(CaptureStatus.FOR_SUBTYPING, constructor.newTypeConstructor!!,
lowerType, type.annotations, type.isMarkedNullable) lowerType, type.annotations, type.isMarkedNullable)
return newCapturedType
} }
is IntegerValueTypeConstructor -> { is IntegerValueTypeConstructor -> {
@@ -448,12 +448,11 @@ fun createSpacingBuilder(settings: CodeStyleSettings, builderUtil: KotlinSpacing
.customRule { _, _, right -> .customRule { _, _, right ->
val rightNode = right.node!! val rightNode = right.node!!
val rightType = rightNode.elementType val rightType = rightNode.elementType
val numSpaces = spacesInSimpleFunction
if (rightType == VALUE_PARAMETER_LIST) { if (rightType == VALUE_PARAMETER_LIST) {
createSpacing(numSpaces, keepLineBreaks = false) createSpacing(spacesInSimpleFunction, keepLineBreaks = false)
} }
else { else {
createSpacing(numSpaces) createSpacing(spacesInSimpleFunction)
} }
} }
@@ -120,8 +120,7 @@ fun collectAllModuleInfosFromIdeaModel(project: Project): List<IdeaModuleInfo> {
val sdksInfos = (sdksFromModulesDependencies + getAllProjectSdks()).filterNotNull().toSet().map { SdkInfo(project, it) } val sdksInfos = (sdksFromModulesDependencies + getAllProjectSdks()).filterNotNull().toSet().map { SdkInfo(project, it) }
val collectAllModuleInfos = modulesSourcesInfos + librariesInfos + sdksInfos return modulesSourcesInfos + librariesInfos + sdksInfos
return collectAllModuleInfos
} }
private fun createBuiltIns(settings: PlatformAnalysisSettings, sdkContext: GlobalContextImpl): KotlinBuiltIns = when { private fun createBuiltIns(settings: PlatformAnalysisSettings, sdkContext: GlobalContextImpl): KotlinBuiltIns = when {
@@ -85,9 +85,8 @@ class ScriptExternalHighlightingPass(
private fun Int.coerceLineIn(document: Document) = coerceIn(0, document.lineCount - 1) private fun Int.coerceLineIn(document: Document) = coerceIn(0, document.lineCount - 1)
private fun Document.offsetBy(line: Int, col: Int): Int { private fun Document.offsetBy(line: Int, col: Int): Int {
val offset = (getLineStartOffset(line) + col). return (getLineStartOffset(line) + col).
coerceIn(getLineStartOffset(line), getLineEndOffset(line)) coerceIn(getLineStartOffset(line), getLineEndOffset(line))
return offset
} }
private fun ScriptReport.Severity.convertSeverity(): HighlightSeverity? { private fun ScriptReport.Severity.convertSeverity(): HighlightSeverity? {
@@ -177,19 +177,18 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName:
} }
private fun analyzeSingleImport(result: Result, importedFqName: FqName?, isAllUnder: Boolean, aliasName: String?): Result { private fun analyzeSingleImport(result: Result, importedFqName: FqName?, isAllUnder: Boolean, aliasName: String?): Result {
val qName = importedFqName
if (!isAllUnder) { if (!isAllUnder) {
if (qName?.asString() == targetClassFqName && if (importedFqName?.asString() == targetClassFqName &&
(aliasName == null || aliasName == targetShortName)) { (aliasName == null || aliasName == targetShortName)) {
return result.changeTo(Result.Found) return result.changeTo(Result.Found)
} }
else if (qName?.shortName()?.asString() == targetShortName && else if (importedFqName?.shortName()?.asString() == targetShortName &&
qName.parent().asString() in conflictingPackages && importedFqName.parent().asString() in conflictingPackages &&
aliasName == null) { aliasName == null) {
return result.changeTo(Result.FoundOther) return result.changeTo(Result.FoundOther)
} }
else if (qName?.shortName()?.asString() == targetShortName && else if (importedFqName?.shortName()?.asString() == targetShortName &&
qName.parent().asString() in packagesWithTypeAliases && importedFqName.parent().asString() in packagesWithTypeAliases &&
aliasName == null) { aliasName == null) {
return Result.Ambiguity return Result.Ambiguity
} }
@@ -199,9 +198,9 @@ class PsiBasedClassResolver @TestOnly constructor(private val targetClassFqName:
} }
else { else {
when { when {
qName?.asString() == targetPackage -> return result.changeTo(Result.Found) importedFqName?.asString() == targetPackage -> return result.changeTo(Result.Found)
qName?.asString() in conflictingPackages -> return result.changeTo(Result.FoundOther) importedFqName?.asString() in conflictingPackages -> return result.changeTo(Result.FoundOther)
qName?.asString() in packagesWithTypeAliases -> return Result.Ambiguity importedFqName?.asString() in packagesWithTypeAliases -> return Result.Ambiguity
} }
} }
return result return result
@@ -37,14 +37,12 @@ class CommentSaver(originalElements: PsiChildRange, private val saveLineBreaks:
companion object { companion object {
fun create(element: PsiElement): TreeElement? { fun create(element: PsiElement): TreeElement? {
val tokenType = element.tokenType val tokenType = element.tokenType
val treeElement = when { return when {
element is PsiWhiteSpace -> if (element.textContains('\n')) LineBreakTreeElement() else null element is PsiWhiteSpace -> if (element.textContains('\n')) LineBreakTreeElement() else null
element is PsiComment -> CommentTreeElement.create(element) element is PsiComment -> CommentTreeElement.create(element)
tokenType != null -> TokenTreeElement(tokenType) tokenType != null -> TokenTreeElement(tokenType)
else -> if (element.textLength > 0) StandardTreeElement() else null // don't save empty elements else -> if (element.textLength > 0) StandardTreeElement() else null // don't save empty elements
} }
// treeElement?.debugText = element.getText()
return treeElement
} }
} }
@@ -52,7 +52,7 @@ internal fun KtClass.findComponentDeclarationInManifest(manifest: Manifest): And
val application = manifest.application ?: return null val application = manifest.application ?: return null
val type = (resolveToDescriptor(BodyResolveMode.PARTIAL) as? ClassDescriptor)?.defaultType ?: return null val type = (resolveToDescriptor(BodyResolveMode.PARTIAL) as? ClassDescriptor)?.defaultType ?: return null
val component = when { return when {
type.isSubclassOf(AndroidUtils.ACTIVITY_BASE_CLASS_NAME) -> type.isSubclassOf(AndroidUtils.ACTIVITY_BASE_CLASS_NAME) ->
application.activities?.find { it.activityClass.value?.qualifiedName == fqName?.asString() }?.activityClass application.activities?.find { it.activityClass.value?.qualifiedName == fqName?.asString() }?.activityClass
type.isSubclassOf(AndroidUtils.SERVICE_CLASS_NAME) -> type.isSubclassOf(AndroidUtils.SERVICE_CLASS_NAME) ->
@@ -63,8 +63,6 @@ internal fun KtClass.findComponentDeclarationInManifest(manifest: Manifest): And
application.providers?.find { it.providerClass.value?.qualifiedName == fqName?.asString() }?.providerClass application.providers?.find { it.providerClass.value?.qualifiedName == fqName?.asString() }?.providerClass
else -> null else -> null
} }
return component
} }
internal fun PsiElement.getAndroidFacetForFile(): AndroidFacet? { internal fun PsiElement.getAndroidFacetForFile(): AndroidFacet? {
@@ -194,8 +194,7 @@ class NewKotlinActivityAction: AnAction(KotlinIcons.ACTIVITY) {
val project = e.project val project = e.project
if (project == null || project.isDisposed) return null if (project == null || project.isDisposed) return null
val module = LangDataKeys.MODULE.getData(e.dataContext) val module = LangDataKeys.MODULE.getData(e.dataContext)
val facet = if (module != null) AndroidFacet.getInstance(module) else null return if (module != null) AndroidFacet.getInstance(module) else null
return facet
} }
private fun isVisible(facet: AndroidFacet): Boolean { private fun isVisible(facet: AndroidFacet): Boolean {
@@ -90,7 +90,7 @@ object LambdaItems {
explicitParameterTypes: Boolean explicitParameterTypes: Boolean
): LookupElement { ): LookupElement {
val lookupString = LambdaSignatureTemplates.lambdaPresentation(functionType, signaturePresentation) val lookupString = LambdaSignatureTemplates.lambdaPresentation(functionType, signaturePresentation)
val lookupElement = LookupElementBuilder.create(lookupString) return LookupElementBuilder.create(lookupString)
.withInsertHandler({ context, lookupElement -> .withInsertHandler({ context, lookupElement ->
val offset = context.startOffset val offset = context.startOffset
val placeholder = "{}" val placeholder = "{}"
@@ -101,6 +101,5 @@ object LambdaItems {
.suppressAutoInsertion() .suppressAutoInsertion()
.assignSmartCompletionPriority(SmartCompletionItemPriority.LAMBDA) .assignSmartCompletionPriority(SmartCompletionItemPriority.LAMBDA)
.addTailAndNameSimilarity(functionExpectedInfos.filter { it.fuzzyType?.type == functionType }) .addTailAndNameSimilarity(functionExpectedInfos.filter { it.fuzzyType?.type == functionType })
return lookupElement
} }
} }
@@ -73,7 +73,7 @@ object LambdaSignatureItems {
SmartCompletionItemPriority.LAMBDA_SIGNATURE_EXPLICIT_PARAMETER_TYPES SmartCompletionItemPriority.LAMBDA_SIGNATURE_EXPLICIT_PARAMETER_TYPES
else else
SmartCompletionItemPriority.LAMBDA_SIGNATURE SmartCompletionItemPriority.LAMBDA_SIGNATURE
val lookupElement = LookupElementBuilder.create(lookupString) return LookupElementBuilder.create(lookupString)
.withInsertHandler({ context, lookupElement -> .withInsertHandler({ context, lookupElement ->
val offset = context.startOffset val offset = context.startOffset
val placeholder = "{}" val placeholder = "{}"
@@ -82,6 +82,5 @@ object LambdaSignatureItems {
}) })
.suppressAutoInsertion() .suppressAutoInsertion()
.assignSmartCompletionPriority(priority) .assignSmartCompletionPriority(priority)
return lookupElement
} }
} }
@@ -37,8 +37,7 @@ class KotlinScriptDependenciesClassFinder(project: Project,
object : ConcurrentFactoryMap<VirtualFile, PackageDirectoryCache>() { object : ConcurrentFactoryMap<VirtualFile, PackageDirectoryCache>() {
override fun create(file: VirtualFile): PackageDirectoryCache? { override fun create(file: VirtualFile): PackageDirectoryCache? {
val scriptClasspath = scriptDependenciesManager.getScriptClasspath(file) val scriptClasspath = scriptDependenciesManager.getScriptClasspath(file)
val v = createCache(scriptClasspath) return createCache(scriptClasspath)
return v
} }
} }
} }
@@ -42,8 +42,7 @@ class CommandExecutor(private val runner: KotlinConsoleRunner) {
private fun getTrimmedCommandText(): String { private fun getTrimmedCommandText(): String {
val consoleView = runner.consoleView val consoleView = runner.consoleView
val document = consoleView.editorDocument val document = consoleView.editorDocument
val inputText = document.text.trim() return document.text.trim()
return inputText
} }
private fun sendCommandToProcess(command: String) { private fun sendCommandToProcess(command: String) {
@@ -151,13 +151,13 @@ class ReplOutputProcessor(
logError(this::class.java, internalErrorText) logError(this::class.java, internalErrorText)
} }
private fun getAttributesForSeverity(start: Int, end: Int, severity: Severity): TextAttributes { private fun getAttributesForSeverity(start: Int, end: Int, severity: Severity): TextAttributes = when (severity) {
val attributes = when (severity) { Severity.ERROR ->
Severity.ERROR -> getAttributesForSeverity(HighlightInfoType.ERROR, HighlightSeverity.ERROR, CodeInsightColors.ERRORS_ATTRIBUTES, start, end) getAttributesForSeverity(HighlightInfoType.ERROR, HighlightSeverity.ERROR, CodeInsightColors.ERRORS_ATTRIBUTES, start, end)
Severity.WARNING -> getAttributesForSeverity(HighlightInfoType.WARNING, HighlightSeverity.WARNING, CodeInsightColors.WARNINGS_ATTRIBUTES, start, end) Severity.WARNING ->
Severity.INFO -> getAttributesForSeverity(HighlightInfoType.WEAK_WARNING, HighlightSeverity.WEAK_WARNING, CodeInsightColors.WEAK_WARNING_ATTRIBUTES, start, end) getAttributesForSeverity(HighlightInfoType.WARNING, HighlightSeverity.WARNING, CodeInsightColors.WARNINGS_ATTRIBUTES, start, end)
} Severity.INFO ->
return attributes getAttributesForSeverity(HighlightInfoType.WEAK_WARNING, HighlightSeverity.WEAK_WARNING, CodeInsightColors.WEAK_WARNING_ATTRIBUTES, start, end)
} }
private fun getAttributesForSeverity( private fun getAttributesForSeverity(
@@ -113,12 +113,11 @@ class KotlinGenerateToStringAction : KotlinGenerateMemberActionBase<KotlinGenera
protected fun renderVariableValue(variableDescriptor: VariableDescriptor, ref: String): String { protected fun renderVariableValue(variableDescriptor: VariableDescriptor, ref: String): String {
val type = variableDescriptor.type val type = variableDescriptor.type
val rhs = when { return when {
KotlinBuiltIns.isArray(type) || KotlinBuiltIns.isPrimitiveArray(type) -> "\${java.util.Arrays.toString($ref)}" KotlinBuiltIns.isArray(type) || KotlinBuiltIns.isPrimitiveArray(type) -> "\${java.util.Arrays.toString($ref)}"
KotlinBuiltIns.isString(type) -> "'$$ref'" KotlinBuiltIns.isString(type) -> "'$$ref'"
else -> "$$ref" else -> "$$ref"
} }
return rhs
} }
abstract fun generate(info: Info): String abstract fun generate(info: Info): String
@@ -137,8 +137,7 @@ class KotlinSetupEnvironmentNotificationProvider(
} }
} }
} }
val configuratorsPopup = JBPopupFactory.getInstance().createListPopup(step) return JBPopupFactory.getInstance().createListPopup(step)
return configuratorsPopup
} }
} }
} }
@@ -262,7 +262,7 @@ class ConvertTextJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransf
} }
} }
val copiedJavaCode = when (context) { return when (context) {
JavaContext.TOP_LEVEL -> createCopiedJavaCode(prefix, "$", text) JavaContext.TOP_LEVEL -> createCopiedJavaCode(prefix, "$", text)
JavaContext.CLASS_BODY -> createCopiedJavaCode(prefix, "$classDef {\n$\n}", text) JavaContext.CLASS_BODY -> createCopiedJavaCode(prefix, "$classDef {\n$\n}", text)
@@ -271,8 +271,6 @@ class ConvertTextJavaCopyPasteProcessor : CopyPastePostProcessor<TextBlockTransf
JavaContext.EXPRESSION -> createCopiedJavaCode(prefix, "$classDef {\nObject field = $\n}", text) JavaContext.EXPRESSION -> createCopiedJavaCode(prefix, "$classDef {\nObject field = $\n}", text)
} }
return copiedJavaCode
} }
private fun createCopiedJavaCode(prefix: String, templateWithoutPrefix: String, text: String): CopiedJavaCode { private fun createCopiedJavaCode(prefix: String, templateWithoutPrefix: String, text: String): CopiedJavaCode {
@@ -269,9 +269,8 @@ internal fun getLocationsOfInlinedLine(type: ReferenceType, position: SourcePosi
} }
val lines = inlinedLinesNumbers(line + 1, position.file.name, FqName(type.name()), type.sourceName(), project, sourceSearchScope) val lines = inlinedLinesNumbers(line + 1, position.file.name, FqName(type.name()), type.sourceName(), project, sourceSearchScope)
val inlineLocations = lines.flatMap { type.locationsOfLine(it) }
return inlineLocations return lines.flatMap { type.locationsOfLine(it) }
} }
fun isInCrossinlineArgument(ktElement: KtElement): Boolean { fun isInCrossinlineArgument(ktElement: KtElement): Boolean {
@@ -313,13 +312,11 @@ private fun inlinedLinesNumbers(
val mappingsToInlinedFile = smap.fileMappings.filter { it.name == inlineFileName } val mappingsToInlinedFile = smap.fileMappings.filter { it.name == inlineFileName }
val mappingIntervals = mappingsToInlinedFile.flatMap { it.lineMappings } val mappingIntervals = mappingsToInlinedFile.flatMap { it.lineMappings }
val mappedLines = mappingIntervals.asSequence(). return mappingIntervals.asSequence().
filter { rangeMapping -> rangeMapping.hasMappingForSource(inlineLineNumber) }. filter { rangeMapping -> rangeMapping.hasMappingForSource(inlineLineNumber) }.
map { rangeMapping -> rangeMapping.mapSourceToDest(inlineLineNumber) }. map { rangeMapping -> rangeMapping.mapSourceToDest(inlineLineNumber) }.
filter { line -> line != -1 }. filter { line -> line != -1 }.
toList() toList()
return mappedLines
} }
@Volatile var emulateDexDebugInTests: Boolean = false @Volatile var emulateDexDebugInTests: Boolean = false
@@ -186,8 +186,7 @@ private fun getInlineFunctionsIfAny(file: KtFile, offset: Int): List<KtNamedFunc
val descriptor = containingFunction.resolveToDescriptor() val descriptor = containingFunction.resolveToDescriptor()
if (!InlineUtil.isInline(descriptor)) return emptyList() if (!InlineUtil.isInline(descriptor)) return emptyList()
val inlineFunctionsCalls = DebuggerUtils.analyzeElementWithInline(containingFunction, false).filterIsInstance<KtNamedFunction>() return DebuggerUtils.analyzeElementWithInline(containingFunction, false).filterIsInstance<KtNamedFunction>()
return inlineFunctionsCalls
} }
private fun getInlineArgumentsIfAny(inlineFunctionCalls: List<KtCallExpression>): List<KtFunction> { private fun getInlineArgumentsIfAny(inlineFunctionCalls: List<KtCallExpression>): List<KtFunction> {
@@ -191,10 +191,8 @@ abstract class CustomLibraryDescriptorWithDeferredConfig
} }
private val configurator: KotlinWithLibraryConfigurator private val configurator: KotlinWithLibraryConfigurator
get() { get() = getConfiguratorByName(configuratorName) as KotlinWithLibraryConfigurator?
val configurator = getConfiguratorByName(configuratorName) as KotlinWithLibraryConfigurator? ?: error("Configurator with name $configuratorName should exists") ?: error("Configurator with name ${configuratorName} should exists")
return configurator
}
// Implements an API added in IDEA 16 // Implements an API added in IDEA 16
override fun createNewLibraryWithDefaultSettings(contextDirectory: VirtualFile?): NewLibraryConfiguration? { override fun createNewLibraryWithDefaultSettings(contextDirectory: VirtualFile?): NewLibraryConfiguration? {
@@ -166,7 +166,7 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean
} }
private fun createFixes(property: KtProperty, conflictingExtension: SyntheticJavaPropertyDescriptor, isOnTheFly: Boolean): Array<IntentionWrapper> { private fun createFixes(property: KtProperty, conflictingExtension: SyntheticJavaPropertyDescriptor, isOnTheFly: Boolean): Array<IntentionWrapper> {
val fixes = if (isSameAsSynthetic(property, conflictingExtension)) { return if (isSameAsSynthetic(property, conflictingExtension)) {
val fix1 = IntentionWrapper(DeleteRedundantExtensionAction(property), property.containingFile) val fix1 = IntentionWrapper(DeleteRedundantExtensionAction(property), property.containingFile)
// don't add the second fix when on the fly to allow code cleanup // don't add the second fix when on the fly to allow code cleanup
val fix2 = if (isOnTheFly) val fix2 = if (isOnTheFly)
@@ -178,7 +178,6 @@ class ConflictingExtensionPropertyInspection : AbstractKotlinInspection(), Clean
else { else {
emptyArray() emptyArray()
} }
return fixes
} }
private class DeleteRedundantExtensionAction(property: KtProperty) : KotlinQuickFixAction<KtProperty>(property) { private class DeleteRedundantExtensionAction(property: KtProperty) : KotlinQuickFixAction<KtProperty>(property) {
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.idea.intentions package org.jetbrains.kotlin.idea.intentions
import com.intellij.codeInsight.CodeInsightUtil import com.intellij.codeInsight.CodeInsightUtil
import com.intellij.codeInsight.FileModificationService
import com.intellij.codeInsight.daemon.impl.quickfix.CreateClassKind import com.intellij.codeInsight.daemon.impl.quickfix.CreateClassKind
import com.intellij.codeInsight.intention.impl.CreateClassDialog import com.intellij.codeInsight.intention.impl.CreateClassDialog
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
@@ -47,17 +46,16 @@ private const val IMPL_SUFFIX = "Impl"
class CreateKotlinSubClassIntention : SelfTargetingRangeIntention<KtClass>(KtClass::class.java, "Create Kotlin subclass") { class CreateKotlinSubClassIntention : SelfTargetingRangeIntention<KtClass>(KtClass::class.java, "Create Kotlin subclass") {
override fun applicabilityRange(element: KtClass): TextRange? { override fun applicabilityRange(element: KtClass): TextRange? {
val baseClass = element if (element.name == null || element.getParentOfType<KtFunction>(true) != null) {
if (baseClass.name == null || baseClass.getParentOfType<KtFunction>(true) != null) {
// Local / anonymous classes are not supported // Local / anonymous classes are not supported
return null return null
} }
if (!baseClass.isInterface() && !baseClass.isSealed() && !baseClass.isAbstract() && !baseClass.hasModifier(KtTokens.OPEN_KEYWORD)) { if (!element.isInterface() && !element.isSealed() && !element.isAbstract() && !element.hasModifier(KtTokens.OPEN_KEYWORD)) {
return null return null
} }
val primaryConstructor = baseClass.primaryConstructor val primaryConstructor = element.primaryConstructor
if (!baseClass.isInterface() && primaryConstructor != null) { if (!element.isInterface() && primaryConstructor != null) {
val constructors = baseClass.secondaryConstructors + primaryConstructor val constructors = element.secondaryConstructors + primaryConstructor
if (constructors.none() { if (constructors.none() {
!it.isPrivate() && !it.isPrivate() &&
it.getValueParameters().all { it.hasDefaultValue() } it.getValueParameters().all { it.hasDefaultValue() }
@@ -67,8 +65,8 @@ class CreateKotlinSubClassIntention : SelfTargetingRangeIntention<KtClass>(KtCla
return null return null
} }
} }
text = getImplementTitle(baseClass) text = getImplementTitle(element)
return TextRange(baseClass.startOffset, baseClass.getBody()?.lBrace?.startOffset ?: baseClass.endOffset) return TextRange(element.startOffset, element.getBody()?.lBrace?.startOffset ?: element.endOffset)
} }
private fun getImplementTitle(baseClass: KtClass) = private fun getImplementTitle(baseClass: KtClass) =
@@ -85,12 +83,11 @@ class CreateKotlinSubClassIntention : SelfTargetingRangeIntention<KtClass>(KtCla
if (editor == null) throw IllegalArgumentException("This intention requires an editor") if (editor == null) throw IllegalArgumentException("This intention requires an editor")
val name = element.name ?: throw IllegalStateException("This intention should not be applied to anonymous classes") val name = element.name ?: throw IllegalStateException("This intention should not be applied to anonymous classes")
val baseClass = element if (element.isSealed()) {
if (baseClass.isSealed()) { createSealedSubclass(element, name, editor)
createSealedSubclass(baseClass, name, editor)
} }
else { else {
createExternalSubclass(baseClass, name, editor) createExternalSubclass(element, name, editor)
} }
} }
@@ -96,8 +96,7 @@ class AddNameToArgumentFix(argument: KtValueArgument) : KotlinQuickFixAction<KtV
private fun createArgumentWithName(name: Name): KtValueArgument { private fun createArgumentWithName(name: Name): KtValueArgument {
val argumentExpression = element!!.getArgumentExpression()!! val argumentExpression = element!!.getArgumentExpression()!!
val newArgument = KtPsiFactory(element!!).createArgument(argumentExpression, name, element!!.getSpreadElement() != null) return KtPsiFactory(element!!).createArgument(argumentExpression, name, element!!.getSpreadElement() != null)
return newArgument
} }
private fun chooseNameAndAdd(project: Project, editor: Editor, names: List<Name>) { private fun chooseNameAndAdd(project: Project, editor: Editor, names: List<Name>) {
@@ -68,7 +68,8 @@ abstract class KotlinIntentionActionFactoryWithDelegate<E : KtElement, D : Any>
// Cache data so that it can be shared between quick fixes bound to the same element & diagnostic // Cache data so that it can be shared between quick fixes bound to the same element & diagnostic
// Cache null values // Cache null values
val cachedData: Ref<D> = Ref.create(extractFixData(originalElement, diagnostic)) val cachedData: Ref<D> = Ref.create(extractFixData(originalElement, diagnostic))
val actions: List<QuickFixWithDelegateFactory> = try {
return try {
createFixes(originalElementPointer, diagnostic) factory@ { createFixes(originalElementPointer, diagnostic) factory@ {
val element = originalElementPointer.element ?: return@factory null val element = originalElementPointer.element ?: return@factory null
val diagnosticElement = diagnosticElementPointer.element ?: return@factory null val diagnosticElement = diagnosticElementPointer.element ?: return@factory null
@@ -86,7 +87,5 @@ abstract class KotlinIntentionActionFactoryWithDelegate<E : KtElement, D : Any>
finally { finally {
cachedData.set(null) // Do not keep cache after all actions are initialized cachedData.set(null) // Do not keep cache after all actions are initialized
} }
return actions
} }
} }
@@ -159,8 +159,7 @@ fun KtExpression.guessTypes(
} }
parent is KtTypeConstraint -> { parent is KtTypeConstraint -> {
// expression is on the left side of a type assertion // expression is on the left side of a type assertion
val constraint = parent arrayOf(context[BindingContext.TYPE, parent.boundTypeReference]!!)
arrayOf(context[BindingContext.TYPE, constraint.boundTypeReference]!!)
} }
this is KtDestructuringDeclarationEntry -> { this is KtDestructuringDeclarationEntry -> {
// expression is on the lhs of a multi-declaration // expression is on the lhs of a multi-declaration
@@ -188,15 +187,14 @@ fun KtExpression.guessTypes(
} }
parent is KtProperty && parent.isLocal -> { parent is KtProperty && parent.isLocal -> {
// the expression is the RHS of a variable assignment with a specified type // the expression is the RHS of a variable assignment with a specified type
val variable = parent val typeRef = parent.typeReference
val typeRef = variable.typeReference
if (typeRef != null) { if (typeRef != null) {
// and has a specified type // and has a specified type
arrayOf(context[BindingContext.TYPE, typeRef]!!) arrayOf(context[BindingContext.TYPE, typeRef]!!)
} }
else { else {
// otherwise guess, based on LHS // otherwise guess, based on LHS
variable.guessType(context) parent.guessType(context)
} }
} }
parent is KtPropertyDelegate -> { parent is KtPropertyDelegate -> {
@@ -32,14 +32,12 @@ abstract class CreateClassFromUsageFactory<E : KtElement> : KotlinIntentionActio
): List<QuickFixWithDelegateFactory> { ): List<QuickFixWithDelegateFactory> {
val possibleClassKinds = getPossibleClassKinds(originalElementPointer.element ?: return emptyList(), diagnostic) val possibleClassKinds = getPossibleClassKinds(originalElementPointer.element ?: return emptyList(), diagnostic)
val classFixes = possibleClassKinds.map { classKind -> return possibleClassKinds.map { classKind ->
QuickFixWithDelegateFactory(classKind.actionPriority) { QuickFixWithDelegateFactory(classKind.actionPriority) {
val currentElement = originalElementPointer.element ?: return@QuickFixWithDelegateFactory null val currentElement = originalElementPointer.element ?: return@QuickFixWithDelegateFactory null
val data = quickFixDataFactory() ?: return@QuickFixWithDelegateFactory null val data = quickFixDataFactory() ?: return@QuickFixWithDelegateFactory null
CreateClassFromUsageFix.create(currentElement, data.copy(kind = classKind)) CreateClassFromUsageFix.create(currentElement, data.copy(kind = classKind))
} }
} }
return classFixes
} }
} }
@@ -513,8 +513,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
val parameterNames = HashSet<String>() val parameterNames = HashSet<String>()
val function = info.method val function = info.method
val element = function val bindingContext = (function as KtElement).analyze(BodyResolveMode.FULL)
val bindingContext = (element as KtElement).analyze(BodyResolveMode.FULL)
val oldDescriptor = ktChangeInfo.originalBaseFunctionDescriptor val oldDescriptor = ktChangeInfo.originalBaseFunctionDescriptor
val containingDeclaration = oldDescriptor.containingDeclaration val containingDeclaration = oldDescriptor.containingDeclaration
@@ -557,7 +556,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
val parameterName = parameter.name val parameterName = parameter.name
if (!parameterNames.add(parameterName)) { if (!parameterNames.add(parameterName)) {
result.putValue(element, "Duplicating parameter '$parameterName'") result.putValue(function, "Duplicating parameter '$parameterName'")
} }
if (parametersScope != null) { if (parametersScope != null) {
@@ -91,7 +91,7 @@ class MoveKotlinFileHandler : MoveFileHandler() {
} }
} }
val declarationMoveProcessor = MoveKotlinDeclarationsProcessor( return MoveKotlinDeclarationsProcessor(
MoveDeclarationsDescriptor( MoveDeclarationsDescriptor(
project = project, project = project,
elementsToMove = psiFile.declarations.filterIsInstance<KtNamedDeclaration>(), elementsToMove = psiFile.declarations.filterIsInstance<KtNamedDeclaration>(),
@@ -102,7 +102,6 @@ class MoveKotlinFileHandler : MoveFileHandler() {
), ),
Mover.Idle Mover.Idle
) )
return declarationMoveProcessor
} }
override fun canProcessElement(element: PsiFile?): Boolean { override fun canProcessElement(element: PsiFile?): Boolean {
@@ -70,11 +70,10 @@ fun addMemberToTarget(targetMember: KtNamedDeclaration, targetClass: KtClassOrOb
} }
val anchor = targetClass.declarations.filterIsInstance(targetMember::class.java).lastOrNull() val anchor = targetClass.declarations.filterIsInstance(targetMember::class.java).lastOrNull()
val movedMember = when { return when {
anchor == null && targetMember is KtProperty -> targetClass.addDeclarationBefore(targetMember, null) anchor == null && targetMember is KtProperty -> targetClass.addDeclarationBefore(targetMember, null)
else -> targetClass.addDeclarationAfter(targetMember, anchor) else -> targetClass.addDeclarationAfter(targetMember, anchor)
} }
return movedMember
} }
private fun KtParameter.needToBeAbstract(targetClass: KtClassOrObject): Boolean { private fun KtParameter.needToBeAbstract(targetClass: KtClassOrObject): Boolean {
@@ -335,12 +335,11 @@ fun getStdlibArtifactId(sdk: Sdk?, version: String): String {
} }
val sdkVersion = sdk?.let { JavaSdk.getInstance().getVersion(it) } val sdkVersion = sdk?.let { JavaSdk.getInstance().getVersion(it) }
val artifactId = when (sdkVersion) { return when (sdkVersion) {
JavaSdkVersion.JDK_1_8, JavaSdkVersion.JDK_1_9 -> MAVEN_STDLIB_ID_JRE8 JavaSdkVersion.JDK_1_8, JavaSdkVersion.JDK_1_9 -> MAVEN_STDLIB_ID_JRE8
JavaSdkVersion.JDK_1_7 -> MAVEN_STDLIB_ID_JRE7 JavaSdkVersion.JDK_1_7 -> MAVEN_STDLIB_ID_JRE7
else -> MAVEN_STDLIB_ID else -> MAVEN_STDLIB_ID
} }
return artifactId
} }
fun getDefaultJvmTarget(sdk: Sdk?, version: String): JvmTarget? { fun getDefaultJvmTarget(sdk: Sdk?, version: String): JvmTarget? {
@@ -77,7 +77,7 @@ class ConstructorConverter(
modifiers: Modifiers, modifiers: Modifiers,
fieldsToDrop: MutableSet<PsiField>, fieldsToDrop: MutableSet<PsiField>,
postProcessBody: (Block) -> Block): Constructor? { postProcessBody: (Block) -> Block): Constructor? {
val result = if (constructor == primaryConstructor) { return if (constructor == primaryConstructor) {
convertPrimaryConstructor(annotations, modifiers, fieldsToDrop, postProcessBody) convertPrimaryConstructor(annotations, modifiers, fieldsToDrop, postProcessBody)
} }
else { else {
@@ -104,7 +104,6 @@ class ConstructorConverter(
SecondaryConstructor(annotations, modifiers, params, converter.deferredElement(::convertBody), thisOrSuperDeferred) SecondaryConstructor(annotations, modifiers, params, converter.deferredElement(::convertBody), thisOrSuperDeferred)
} }
return result
} }
private fun findThisOrSuperCall(constructor: PsiMethod): PsiExpressionStatement? { private fun findThisOrSuperCall(constructor: PsiMethod): PsiExpressionStatement? {
@@ -378,11 +378,10 @@ internal class ExpressionDecomposer private constructor(
get() = name.makeRef() get() = name.makeRef()
fun assign(value: JsExpression): JsStatement { fun assign(value: JsExpression): JsStatement {
val statement = JsExpressionStatement(assignment(nameRef, value)).apply { return JsExpressionStatement(assignment(nameRef, value)).apply {
synthetic = true synthetic = true
expression.source = sourceInfo ?: value.source expression.source = sourceInfo ?: value.source
} }
return statement
} }
} }
@@ -51,8 +51,7 @@ object ExceptionPropertyIntrinsicFactory : FunctionIntrinsicFactory {
.getContributedDescriptors(DescriptorKindFilter.CALLABLES) .getContributedDescriptors(DescriptorKindFilter.CALLABLES)
.filterIsInstance<PropertyDescriptor>() .filterIsInstance<PropertyDescriptor>()
.first { it.overriddenDescriptors.any { it == property } } .first { it.overriddenDescriptors.any { it == property } }
val fieldRef = JsAstUtils.pureFqn(context.getNameForBackingField(currentClassProperty), callInfo.dispatchReceiver!!) return JsAstUtils.pureFqn(context.getNameForBackingField(currentClassProperty), callInfo.dispatchReceiver!!)
return fieldRef
} }
} }
} }
@@ -124,18 +124,15 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory {
override fun getSupportTokens() = OperatorConventions.EQUALS_OPERATIONS!! override fun getSupportTokens() = OperatorConventions.EQUALS_OPERATIONS!!
override fun getIntrinsic(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): BinaryOperationIntrinsic? { override fun getIntrinsic(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): BinaryOperationIntrinsic? =
val result = when { when {
isEnumIntrinsicApplicable(descriptor, leftType, rightType) -> EnumEqualsIntrinsic isEnumIntrinsicApplicable(descriptor, leftType, rightType) -> EnumEqualsIntrinsic
KotlinBuiltIns.isBuiltIn(descriptor) || KotlinBuiltIns.isBuiltIn(descriptor) ||
TopLevelFIF.EQUALS_IN_ANY.test(descriptor) -> EqualsIntrinsic TopLevelFIF.EQUALS_IN_ANY.test(descriptor) -> EqualsIntrinsic
else -> null else -> null
} }
return result
}
private fun isEnumIntrinsicApplicable(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): Boolean { private fun isEnumIntrinsicApplicable(descriptor: FunctionDescriptor, leftType: KotlinType?, rightType: KotlinType?): Boolean {
return DescriptorUtils.isEnumClass(descriptor.containingDeclaration) && leftType != null && rightType != null && return DescriptorUtils.isEnumClass(descriptor.containingDeclaration) && leftType != null && rightType != null &&
@@ -125,7 +125,7 @@ fun <T, S> List<T>.splitToRanges(classifier: (T) -> S): List<Pair<List<T>, S>> {
fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpression { fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpression {
val classifierDescriptor = type.constructor.declarationDescriptor val classifierDescriptor = type.constructor.declarationDescriptor
val referenceToJsClass: JsExpression = when (classifierDescriptor) { return when (classifierDescriptor) {
is ClassDescriptor -> { is ClassDescriptor -> {
ReferenceTranslator.translateAsTypeReference(classifierDescriptor, context) ReferenceTranslator.translateAsTypeReference(classifierDescriptor, context)
} }
@@ -140,8 +140,6 @@ fun getReferenceToJsClass(type: KotlinType, context: TranslationContext): JsExpr
throw IllegalStateException("Can't get reference for $type") throw IllegalStateException("Can't get reference for $type")
} }
} }
return referenceToJsClass
} }
fun TranslationContext.addFunctionToPrototype( fun TranslationContext.addFunctionToPrototype(
@@ -385,9 +385,7 @@ internal object KotlinConverter {
val file = createAnalyzableFile("dummy.kt", text, context) val file = createAnalyzableFile("dummy.kt", text, context)
val declarations = file.declarations val declarations = file.declarations
assert(declarations.size == 1) { "${declarations.size} declarations in $text" } assert(declarations.size == 1) { "${declarations.size} declarations in $text" }
@Suppress("UNCHECKED_CAST") return declarations.first() as TDeclaration
val result = declarations.first() as TDeclaration
return result
} }
internal fun KtContainerNode.getExpression(): KtExpression? = internal fun KtContainerNode.getExpression(): KtExpression? =