From 392a75e6b87c73adc301b9d13fcc96ee85fb05d8 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Wed, 25 Sep 2019 17:40:48 +0300 Subject: [PATCH] New J2K: use KotlinExceptionWithAttachments to report tree building errors Also, try not to throw exceptions when possible --- .../inference/common/BoundTypeCalculator.kt | 2 +- ...rtGettersAndSettersToPropertyProcessing.kt | 4 +- .../processings/diagnosticBasedProcessings.kt | 2 +- .../processings/inspeсtionLikeProcessings.kt | 10 +-- .../kotlin/nj2k/JavaToJKTreeBuilder.kt | 61 +++++++++++-------- .../ClassToObjectPromotionConversion.kt | 7 ++- .../conversions/DefaultArgumentsConversion.kt | 3 +- .../conversions/EnumFieldAccessConversion.kt | 11 ++-- .../conversions/ImplicitCastsConversion.kt | 8 +-- .../ImplicitInitializerConversion.kt | 2 +- .../MethodReferenceToLambdaConversion.kt | 6 +- .../OperatorExpressionConversion.kt | 4 +- .../conversions/SwitchStatementConversion.kt | 2 +- .../kotlin/nj2k/symbols/JKFieldSymbol.kt | 12 ++-- .../jetbrains/kotlin/nj2k/tree/expressions.kt | 22 +++---- .../jetbrains/kotlin/nj2k/tree/modifiers.kt | 3 +- .../kotlin/nj2k/types/JKTypeFactory.kt | 4 +- .../jetbrains/kotlin/nj2k/types/typesUtils.kt | 4 +- 18 files changed, 93 insertions(+), 74 deletions(-) diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/inference/common/BoundTypeCalculator.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/inference/common/BoundTypeCalculator.kt index 496c2e3a7df..8bb27875082 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/inference/common/BoundTypeCalculator.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/inference/common/BoundTypeCalculator.kt @@ -206,7 +206,7 @@ open class BoundTypeCalculatorImpl( arguments.mapIndexed { i, argument -> TypeParameter( argument.type.boundTypeUnenhanced( - typeVariable?.typeParameters?.get(i)?.boundType?.label?.safeAs()?.typeVariable, + typeVariable?.typeParameters?.getOrNull(i)?.boundType?.label?.safeAs()?.typeVariable, contextBoundType, call, isImplicitReceiver, diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/ConvertGettersAndSettersToPropertyProcessing.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/ConvertGettersAndSettersToPropertyProcessing.kt index 76eff2bdd13..b68c70cce6e 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/ConvertGettersAndSettersToPropertyProcessing.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/ConvertGettersAndSettersToPropertyProcessing.kt @@ -77,7 +77,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing ?.returnedExpression ?.unpackedReferenceToProperty() ?.takeIf { - it.type() == this.type()!! + it.type() == type() ?: return@takeIf false } return RealGetter(this, target, name) } @@ -184,7 +184,7 @@ class ConvertGettersAndSettersToPropertyProcessing : ElementsBasedPostProcessing ktSetter.filterModifiers() if (setter is RealSetter) { setter.function.forAllUsages { usage -> - val callExpression = usage.getStrictParentOfType()!! + val callExpression = usage.getStrictParentOfType() ?: return@forAllUsages val qualifier = callExpression.getQualifiedExpressionForSelector() val newValue = callExpression.valueArguments.single() if (qualifier != null) { diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/diagnosticBasedProcessings.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/diagnosticBasedProcessings.kt index 17d210db29b..f04edf3dc71 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/diagnosticBasedProcessings.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/diagnosticBasedProcessings.kt @@ -85,7 +85,7 @@ val removeUselessCastDiagnosticBasedProcessing = val removeInnecessaryNotNullAssertionDiagnosticBasedProcessing = diagnosticBasedProcessing(Errors.UNNECESSARY_NOT_NULL_ASSERTION) { element, _ -> val exclExclExpr = element.parent as KtUnaryExpression - val baseExpression = exclExclExpr.baseExpression!! + val baseExpression = exclExclExpr.baseExpression ?: return@diagnosticBasedProcessing val context = baseExpression.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS) if (context.diagnostics.forElement(element).any { it.factory == Errors.UNNECESSARY_NOT_NULL_ASSERTION }) { exclExclExpr.replace(baseExpression) diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/inspeсtionLikeProcessings.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/inspeсtionLikeProcessings.kt index 44ce6109a76..4fbc93a3b15 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/inspeсtionLikeProcessings.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/processings/inspeсtionLikeProcessings.kt @@ -82,7 +82,7 @@ class RemoveRedundantNullabilityProcessing : InspectionLikeProcessingForElement< override fun apply(element: KtProperty) { val typeElement = element.typeReference?.typeElement - typeElement?.replace(typeElement.cast().innerType!!) + typeElement?.replace(typeElement.safeAs()?.innerType ?: return) } } @@ -269,8 +269,8 @@ class JavaObjectEqualsToEqOperatorProcessing : InspectionLikeProcessingForElemen element.getQualifiedExpressionForSelectorOrThis().replace( factory.createExpressionByPattern( "($0 == $1)", - element.valueArguments[0].getArgumentExpression()!!, - element.valueArguments[1].getArgumentExpression()!! + element.valueArguments[0].getArgumentExpression() ?: return, + element.valueArguments[1].getArgumentExpression() ?: return ) ) } @@ -312,7 +312,7 @@ class RemoveRedundantModalityModifierProcessing : InspectionLikeProcessingForEle } override fun apply(element: KtDeclaration) { - element.removeModifier(element.modalityModifierType()!!) + element.removeModifier(element.modalityModifierType() ?: return) } } @@ -329,7 +329,7 @@ class RemoveRedundantVisibilityModifierProcessing : InspectionLikeProcessingForE } override fun apply(element: KtDeclaration) { - element.removeModifier(element.visibilityModifierType()!!) + element.removeModifier(element.visibilityModifierType() ?: return) } } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt index e557de0f5be..e587dcce2d2 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/JavaToJKTreeBuilder.kt @@ -41,16 +41,17 @@ import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName import org.jetbrains.kotlin.j2k.ReferenceSearcher import org.jetbrains.kotlin.j2k.ast.Nullability import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.nj2k.symbols.* import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.* import org.jetbrains.kotlin.nj2k.types.* - import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration +import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -249,7 +250,7 @@ class JavaToJKTreeBuilder constructor( JavaTokenType.LONG_LITERAL -> JKLiteralExpression(text, LONG) JavaTokenType.FLOAT_LITERAL -> JKLiteralExpression(text, FLOAT) JavaTokenType.DOUBLE_LITERAL -> JKLiteralExpression(text, DOUBLE) - else -> error("Unknown literal element type: ${this.literalElementType}") + else -> throwCanNotConvertError("Unknown literal element type: $literalElementType") }.also { it.assignNonCodeElements(this) } @@ -531,7 +532,7 @@ class JavaToJKTreeBuilder constructor( fun PsiTypeCastExpression.toJK(): JKExpression { return JKTypeCastExpression( operand?.toJK() ?: throwCanNotConvertError(), - castType?.type?.toJK()?.asTypeElement() ?: throwCanNotConvertError() + (castType?.type?.toJK() ?: JKNoType).asTypeElement() ).also { it.assignNonCodeElements(this) } @@ -647,10 +648,12 @@ class JavaToJKTreeBuilder constructor( with(expressionTreeMapper) { argumentList?.toJK() ?: JKArgumentList() }, initializingClass?.createClassBody() ?: JKClassBody(), JKTypeElement( - JKClassType( - symbolProvider.provideDirectSymbol(containingClass ?: throwCanNotConvertError()) as JKClassSymbol, - emptyList() - ) + containingClass?.let { klass -> + JKClassType( + symbolProvider.provideDirectSymbol(klass) as JKClassSymbol, + emptyList() + ) + } ?: JKNoType ) ).also { symbolProvider.provideUniverseSymbol(this, it) @@ -701,15 +704,18 @@ class JavaToJKTreeBuilder constructor( } fun T.annotationList(docCommentOwner: PsiDocCommentOwner?): JKAnnotationList { - val plainAnnotations = annotations.map { it.cast().toJK() } - val deprecatedAnnotation = docCommentOwner?.docComment?.deprecatedAnnotation() ?: return JKAnnotationList(plainAnnotations) - return JKAnnotationList( - plainAnnotations.mapNotNull { annotation -> - if (annotation.classSymbol.fqName == "java.lang.Deprecated") null else annotation - } + deprecatedAnnotation - ) + val deprecatedAnnotation = docCommentOwner?.docComment?.deprecatedAnnotation() + val plainAnnotations = annotations.mapNotNull { annotation -> + when { + annotation !is PsiAnnotation -> null + annotation.qualifiedName == DEPRECATED_ANNOTAION_FQ_NAME && deprecatedAnnotation != null -> null + else -> annotation.toJK() + } + } + return JKAnnotationList(plainAnnotations + listOfNotNull(deprecatedAnnotation)) } + fun PsiAnnotation.toJK(): JKAnnotation = JKAnnotation( symbolProvider.provideSymbolForReference( @@ -755,9 +761,10 @@ class JavaToJKTreeBuilder constructor( fun PsiAnnotationMethod.toJK(): JKJavaAnnotationMethod = JKJavaAnnotationMethod( - returnType?.toJK()?.asTypeElement() - ?: JKTypeElement(JKJavaVoidType).takeIf { isConstructor } - ?: throwCanNotConvertError("type of PsiAnnotationMethod can not be retrieved"), + JKTypeElement( + returnType?.toJK() + ?: JKJavaVoidType.takeIf { isConstructor } + ?: JKNoType), nameIdentifier.toJK(), defaultValue?.toJK() ?: JKStubExpression(), otherModifiers(), @@ -772,9 +779,10 @@ class JavaToJKTreeBuilder constructor( fun PsiMethod.toJK(): JKMethod { return JKMethodImpl( - returnType?.toJK()?.asTypeElement() - ?: JKTypeElement(JKJavaVoidType).takeIf { isConstructor } - ?: throwCanNotConvertError("type of PsiAnnotationMethod can not be retrieved"), + JKTypeElement( + returnType?.toJK() + ?: JKJavaVoidType.takeIf { isConstructor } + ?: JKNoType), nameIdentifier.toJK(), parameterList.parameters.map { it.toJK() }, body?.toJK() ?: JKBodyStub, @@ -845,11 +853,11 @@ class JavaToJKTreeBuilder constructor( is PsiExpressionStatement -> JKExpressionStatement(with(expressionTreeMapper) { expression.toJK() }) is PsiReturnStatement -> JKReturnStatement(with(expressionTreeMapper) { returnValue.toJK() }) is PsiDeclarationStatement -> - JKDeclarationStatement(declaredElements.map { + JKDeclarationStatement(declaredElements.mapNotNull { when (it) { is PsiClass -> it.toJK() is PsiLocalVariable -> it.toJK() - else -> it.throwCanNotConvertError() + else -> null } }) is PsiAssertStatement -> @@ -993,7 +1001,7 @@ class JavaToJKTreeBuilder constructor( this is PsiWhiteSpace -> JKSpaceElement(text) text == ";" -> null text == "" -> null - else -> error("Token should be either token or whitespace") + else -> null } ?: return null tokenCache[this] = token return token @@ -1054,8 +1062,13 @@ class JavaToJKTreeBuilder constructor( also { it.assignNonCodeElements(psi) } private fun PsiElement.throwCanNotConvertError(message: String? = null): Nothing { - error("Cannot convert the following Java element ${this::class} with text `$text`" + message?.let { " due to `$it`" }.orEmpty()) + throw KotlinExceptionWithAttachments("Cannot convert the following Java element ${this::class}" + message?.let { " due to `$it`" }) + .withAttachment("elementText", text) + .withAttachment("file", containingFile?.text) } + companion object { + private const val DEPRECATED_ANNOTAION_FQ_NAME = "java.lang.Deprecated" + } } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ClassToObjectPromotionConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ClassToObjectPromotionConversion.kt index ccd07e66068..d98b9f8b534 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ClassToObjectPromotionConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ClassToObjectPromotionConversion.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.nj2k.conversions +import com.intellij.psi.PsiClass import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext import org.jetbrains.kotlin.nj2k.declarationList import org.jetbrains.kotlin.nj2k.getCompanion @@ -70,6 +71,8 @@ class ClassToObjectPromotionConversion(context: NewJ2kConverterContext) : Recurs } } - private fun JKClass.hasInheritors() = - context.converter.converterServices.oldServices.referenceSearcher.hasInheritors(psi()!!) + private fun JKClass.hasInheritors(): Boolean { + val psi = psi() ?: return false + return context.converter.converterServices.oldServices.referenceSearcher.hasInheritors(psi) + } } \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/DefaultArgumentsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/DefaultArgumentsConversion.kt index 8d579fbbfa9..18a614e291b 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/DefaultArgumentsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/DefaultArgumentsConversion.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.nj2k.conversions +import com.intellij.psi.PsiMethod import org.jetbrains.kotlin.nj2k.* import org.jetbrains.kotlin.nj2k.symbols.JKUniverseMethodSymbol import org.jetbrains.kotlin.nj2k.tree.* @@ -22,7 +23,7 @@ class DefaultArgumentsConversion(context: NewJ2kConverterContext) : RecursiveApp || hasOtherModifier(OtherModifier.OVERRIDE) || hasOtherModifier(OtherModifier.NATIVE) || hasOtherModifier(OtherModifier.SYNCHRONIZED) - || context.converter.converterServices.oldServices.referenceSearcher.hasOverrides(psi()!!) + || psi()?.let { context.converter.converterServices.oldServices.referenceSearcher.hasOverrides(it) } == true || annotationList.annotations.isNotEmpty() || canBeGetterOrSetter() diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/EnumFieldAccessConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/EnumFieldAccessConversion.kt index c53174c77f0..db1872c9351 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/EnumFieldAccessConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/EnumFieldAccessConversion.kt @@ -28,14 +28,15 @@ class EnumFieldAccessConversion(context: NewJ2kConverterContext) : RecursiveAppl ) } - private fun JKFieldSymbol.enumClassSymbol(): JKClassSymbol? = - when { + private fun JKFieldSymbol.enumClassSymbol(): JKClassSymbol? { + return when { this is JKMultiverseFieldSymbol && target is PsiEnumConstant -> - symbolProvider.provideDirectSymbol(target.containingClass!!) as JKClassSymbol + symbolProvider.provideDirectSymbol(target.containingClass ?: return null) as? JKClassSymbol this is JKMultiverseKtEnumEntrySymbol -> - symbolProvider.provideDirectSymbol(target.containingClass()!!) as JKClassSymbol + symbolProvider.provideDirectSymbol(target.containingClass() ?: return null) as? JKClassSymbol this is JKUniverseFieldSymbol && target is JKEnumConstant -> - symbolProvider.provideUniverseSymbol(target.parentOfType()!!) + symbolProvider.provideUniverseSymbol(target.parentOfType() ?: return null) else -> null } + } } \ No newline at end of file diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt index d3366ccbdec..303087b84f4 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitCastsConversion.kt @@ -30,8 +30,8 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic private fun convertBinaryExpression(binaryExpression: JKBinaryExpression): JKExpression { fun JKBinaryExpression.convertBinaryOperationWithChar(): JKBinaryExpression { - val leftType = left.calculateType(typeFactory).asPrimitiveType() ?: return this - val rightType = right.calculateType(typeFactory).asPrimitiveType() ?: return this + val leftType = left.calculateType(typeFactory)?.asPrimitiveType() ?: return this + val rightType = right.calculateType(typeFactory)?.asPrimitiveType() ?: return this val leftOperandCastedCasted by lazy(LazyThreadSafetyMode.NONE) { JKBinaryExpression( @@ -97,7 +97,7 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic private fun JKExpression.castStringToRegex(toType: JKType): JKExpression? { if (toType.safeAs()?.classReference?.fqName != "java.util.regex.Pattern") return null - val expressionType = calculateType(typeFactory) + val expressionType = calculateType(typeFactory) ?: return null if (!expressionType.isStringType()) return null return JKQualifiedExpression( copyTreeAndDetach().parenthesizeIfBinaryExpression(), @@ -117,7 +117,7 @@ class ImplicitCastsConversion(context: NewJ2kConverterContext) : RecursiveApplic val casted = expression.castToAsPrimitiveTypes(toType, strict) ?: return null return JKPrefixExpression(casted, operator) } - val expressionTypeAsPrimitive = calculateType(typeFactory).asPrimitiveType() ?: return null + val expressionTypeAsPrimitive = calculateType(typeFactory)?.asPrimitiveType() ?: return null val toTypeAsPrimitive = toType.asPrimitiveType() ?: return null if (toTypeAsPrimitive == expressionTypeAsPrimitive) return null diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitInitializerConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitInitializerConversion.kt index 2676962680b..30f093daab3 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitInitializerConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ImplicitInitializerConversion.kt @@ -67,7 +67,7 @@ class ImplicitInitializerConversion(context: NewJ2kConverterContext) : Recursive .toMap() .toMutableMap() - val constructorsWithInitializers = findUsages(parentOfType()!!, context).mapNotNull { usage -> + val constructorsWithInitializers = findUsages(containingClass, context).mapNotNull { usage -> val parent = usage.parent val assignmentStatement = when { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt index a92eecce578..0e0ae9494ce 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/MethodReferenceToLambdaConversion.kt @@ -75,8 +75,7 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur JKArgumentList(arguments) ) is JKClassSymbol -> JKNewExpression(symbol, JKArgumentList(), JKTypeArgumentList()) - is JKUnresolvedSymbol -> return recurse(element) - else -> error("Symbol should be either method symbol or class symbol, but it is ${symbol::class}") + else -> return recurse(element) } val qualifier = when { receiverParameter != null -> @@ -94,8 +93,7 @@ class MethodReferenceToLambdaConversion(context: NewJ2kConverterContext) : Recur when (symbol) { is JKMethodSymbol -> symbol.returnType ?: JKNoType is JKClassSymbol -> JKClassType(symbol) - is JKUnresolvedSymbol -> return recurse(element) - else -> error("Symbol should be either method symbol or class symbol, but it is ${symbol::class}") + else -> return recurse(element) } ) ) diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt index 60324605bf5..1546da95901 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/OperatorExpressionConversion.kt @@ -15,8 +15,8 @@ class AnyWithStringConcatenationConversion(context: NewJ2kConverterContext) : Re override fun applyToElement(element: JKTreeElement): JKTreeElement { if (element !is JKBinaryExpression) return recurse(element) if (element.operator.token == JKOperatorToken.PLUS - && element.right.calculateType(typeFactory).isStringType() - && !element.left.calculateType(typeFactory).isStringType() + && element.right.calculateType(typeFactory)?.isStringType() == true + && element.left.calculateType(typeFactory)?.isStringType() == false ) { return recurse( JKBinaryExpression( diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/SwitchStatementConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/SwitchStatementConversion.kt index ee7b0fc0b3b..62cd0f0f863 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/SwitchStatementConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/SwitchStatementConversion.kt @@ -115,7 +115,7 @@ class SwitchStatementConversion(context: NewJ2kConverterContext) : RecursiveAppl this is JKIfElseStatement || this is JKJavaSwitchStatement || this is JKKtWhenStatement -> - this.psi!!.canCompleteNormally() + psi?.canCompleteNormally() == true else -> true } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt index 498dc85bda4..5d5271e1367 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/symbols/JKFieldSymbol.kt @@ -46,11 +46,13 @@ class JKMultiverseKtEnumEntrySymbol( override val typeFactory: JKTypeFactory ) : JKFieldSymbol(), JKMultiverseKtSymbol { override val fieldType: JKType? - get() = JKClassType( - symbolProvider.provideDirectSymbol(target.containingClass()!!) as JKClassSymbol, - emptyList(), - Nullability.NotNull - ) + get() = target.containingClass()?.let { klass -> + JKClassType( + symbolProvider.provideDirectSymbol(klass) as? JKClassSymbol ?: return@let null, + emptyList(), + Nullability.NotNull + ) + } } class JKUnresolvedField( diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/expressions.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/expressions.kt index ec6396686fe..25ed53e279f 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/expressions.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/expressions.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.nj2k.types.* abstract class JKExpression : JKAnnotationMemberValue(), PsiOwner by PsiOwnerImpl() { // we don't need exact type here (eg with substituted type parameters) - abstract fun calculateType(typeFactory: JKTypeFactory): JKType + abstract fun calculateType(typeFactory: JKTypeFactory): JKType? } abstract class JKOperatorExpression : JKExpression() { @@ -92,7 +92,7 @@ class JKLiteralExpression( } class JKStubExpression : JKExpression() { - override fun calculateType(typeFactory: JKTypeFactory) = JKNoType + override fun calculateType(typeFactory: JKTypeFactory): JKType? = null override fun accept(visitor: JKVisitor) = visitor.visitStubExpression(this) } @@ -118,7 +118,7 @@ class JKIfElseExpression( var thenBranch by child(thenBranch) var elseBranch by child(elseBranch) - override fun calculateType(typeFactory: JKTypeFactory): JKType = type + override fun calculateType(typeFactory: JKTypeFactory): JKType? = type override fun accept(visitor: JKVisitor) = visitor.visitIfElseExpression(this) } @@ -133,7 +133,7 @@ class JKLambdaExpression( var functionalType by child(functionalType) val returnType by child(returnType) - override fun calculateType(typeFactory: JKTypeFactory): JKType = JKNoType + override fun calculateType(typeFactory: JKTypeFactory): JKType? = null override fun accept(visitor: JKVisitor) = visitor.visitLambdaExpression(this) } @@ -141,7 +141,7 @@ class JKLambdaExpression( abstract class JKCallExpression : JKExpression(), JKTypeArgumentListOwner { abstract val identifier: JKMethodSymbol abstract var arguments: JKArgumentList - override fun calculateType(typeFactory: JKTypeFactory): JKType = identifier.returnType ?: JKNoType + override fun calculateType(typeFactory: JKTypeFactory): JKType? = identifier.returnType } class JKDelegationConstructorCall( @@ -181,18 +181,18 @@ class JKNewExpression( class JKFieldAccessExpression(var identifier: JKFieldSymbol) : JKExpression() { - override fun calculateType(typeFactory: JKTypeFactory) = identifier.fieldType ?: JKNoType + override fun calculateType(typeFactory: JKTypeFactory) = identifier.fieldType override fun accept(visitor: JKVisitor) = visitor.visitFieldAccessExpression(this) } class JKPackageAccessExpression(var identifier: JKPackageSymbol) : JKExpression() { - override fun calculateType(typeFactory: JKTypeFactory) = JKNoType + override fun calculateType(typeFactory: JKTypeFactory): JKType? = null override fun accept(visitor: JKVisitor) = visitor.visitPackageAccessExpression(this) } class JKClassAccessExpression(var identifier: JKClassSymbol) : JKExpression() { - override fun calculateType(typeFactory: JKTypeFactory) = JKNoType + override fun calculateType(typeFactory: JKTypeFactory): JKType? = null override fun accept(visitor: JKVisitor) = visitor.visitClassAccessExpression(this) } @@ -204,7 +204,7 @@ class JKMethodReferenceExpression( ) : JKExpression() { val qualifier by child(qualifier) val functionalType by child(functionalType) - override fun calculateType(typeFactory: JKTypeFactory): JKType = JKNoType + override fun calculateType(typeFactory: JKTypeFactory): JKType? = null override fun accept(visitor: JKVisitor) = visitor.visitMethodReferenceExpression(this) } @@ -221,7 +221,7 @@ class JKClassLiteralExpression( var literalType: ClassLiteralType ) : JKExpression() { val classType: JKTypeElement by child(classType) - override fun calculateType(typeFactory: JKTypeFactory): JKType = when (literalType) { + override fun calculateType(typeFactory: JKTypeFactory): JKType? = when (literalType) { ClassLiteralType.KOTLIN_CLASS -> typeFactory.types.kotlinClass else -> typeFactory.types.javaKlass } @@ -289,7 +289,7 @@ class JKKtAnnotationArrayInitializerExpression(initializers: List by children(initializers) - override fun calculateType(typeFactory: JKTypeFactory) = JKNoType + override fun calculateType(typeFactory: JKTypeFactory): JKType? = null override fun accept(visitor: JKVisitor) = visitor.visitKtAnnotationArrayInitializerExpression(this) } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/modifiers.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/modifiers.kt index a72b524979c..d31b968ad80 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/tree/modifiers.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/tree/modifiers.kt @@ -43,7 +43,7 @@ enum class OtherModifier(override val text: String) : Modifier { VOLATILE("volatile") } -abstract class JKModifierElement : JKTreeElement() +sealed class JKModifierElement : JKTreeElement() interface JKOtherModifiersOwner : JKModifiersListOwner { @@ -131,7 +131,6 @@ val JKModifierElement.modifier: Modifier is JKModalityModifierElement -> modality is JKVisibilityModifierElement -> visibility is JKOtherModifierElement -> otherModifier - else -> error("") } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt index 2997f34951d..f6702f2eb58 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt @@ -107,7 +107,9 @@ class JKTypeFactory(val symbolProvider: JKSymbolProvider) { } is PsiCapturedWildcardType -> JKCapturedType(fromPsiType(type.wildcard) as JKWildCardType) - else -> throw Exception("Invalid PSI ${this::class.java}") + is PsiIntersectionType -> // TODO what to do with intersection types? old j2k just took the first conjunct + fromPsiType(type.representative) + else -> throw Exception("Invalid PSI ${type::class.java}") } private fun createKotlinType(type: KotlinType): JKType { diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/types/typesUtils.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/types/typesUtils.kt index 198c0faf0fc..9cbea5edb2c 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/types/typesUtils.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/types/typesUtils.kt @@ -78,7 +78,7 @@ fun JKType.applyRecursive(transform: (JKType) -> JKType?): JKType = is JKJavaDisjunctionType -> JKJavaDisjunctionType(disjunctions.map { it.applyRecursive(transform) }, nullability) is JKStarProjectionType -> this - else -> TODO(this::class.toString()) + else -> this } inline fun T.updateNullability(newNullability: Nullability): T = @@ -92,7 +92,7 @@ inline fun T.updateNullability(newNullability: Nullability) is JKJavaArrayType -> JKJavaArrayType(type, newNullability) is JKContextType -> JKContextType is JKJavaDisjunctionType -> this - else -> TODO(this::class.toString()) + else -> this } as T @Suppress("UNCHECKED_CAST")