Avoid getting descriptors for collection literals from built-ins scope
#KT-18845 Fixed
This commit is contained in:
@@ -66,6 +66,8 @@ public interface Errors {
|
|||||||
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> UNSUPPORTED_FEATURE = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> UNSUPPORTED_FEATURE = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, Throwable> EXCEPTION_FROM_ANALYZER = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, Throwable> EXCEPTION_FROM_ANALYZER = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
|
DiagnosticFactory1<PsiElement, String> MISSING_STDLIB = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> EXPERIMENTAL_FEATURE_WARNING = DiagnosticFactory1.create(WARNING);
|
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> EXPERIMENTAL_FEATURE_WARNING = DiagnosticFactory1.create(WARNING);
|
||||||
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> EXPERIMENTAL_FEATURE_ERROR = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> EXPERIMENTAL_FEATURE_ERROR = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
|
|||||||
+1
@@ -578,6 +578,7 @@ public class DefaultErrorMessages {
|
|||||||
MAP.put(EXPERIMENTAL_FEATURE_ERROR, "{0}", new LanguageFeatureMessageRenderer(LanguageFeatureMessageRenderer.Type.ERROR));
|
MAP.put(EXPERIMENTAL_FEATURE_ERROR, "{0}", new LanguageFeatureMessageRenderer(LanguageFeatureMessageRenderer.Type.ERROR));
|
||||||
|
|
||||||
MAP.put(EXCEPTION_FROM_ANALYZER, "Internal Error occurred while analyzing this expression:\n{0}", THROWABLE);
|
MAP.put(EXCEPTION_FROM_ANALYZER, "Internal Error occurred while analyzing this expression:\n{0}", THROWABLE);
|
||||||
|
MAP.put(MISSING_STDLIB, "{0}. Ensure you have the standard Kotlin library in dependencies", STRING);
|
||||||
MAP.put(UNNECESSARY_SAFE_CALL, "Unnecessary safe call on a non-null receiver of type {0}", RENDER_TYPE);
|
MAP.put(UNNECESSARY_SAFE_CALL, "Unnecessary safe call on a non-null receiver of type {0}", RENDER_TYPE);
|
||||||
MAP.put(UNEXPECTED_SAFE_CALL, "Safe-call is not allowed here");
|
MAP.put(UNEXPECTED_SAFE_CALL, "Safe-call is not allowed here");
|
||||||
MAP.put(UNNECESSARY_NOT_NULL_ASSERTION, "Unnecessary non-null assertion (!!) on a non-null receiver of type {0}", RENDER_TYPE);
|
MAP.put(UNNECESSARY_NOT_NULL_ASSERTION, "Unnecessary non-null assertion (!!) on a non-null receiver of type {0}", RENDER_TYPE);
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED_FEATURE
|
|
||||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
import org.jetbrains.kotlin.psi.KtAnnotationEntry
|
||||||
@@ -39,43 +39,47 @@ import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
|
|||||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
|
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
|
||||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo
|
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.noTypeInfo
|
||||||
|
|
||||||
object CollectionLiteralResolver {
|
class CollectionLiteralResolver(val module: ModuleDescriptor, val callResolver: CallResolver, val languageVersionSettings: LanguageVersionSettings) {
|
||||||
val PRIMITIVE_TYPE_TO_ARRAY: Map<PrimitiveType, Name> = hashMapOf(
|
companion object {
|
||||||
PrimitiveType.BOOLEAN to Name.identifier("booleanArrayOf"),
|
val PRIMITIVE_TYPE_TO_ARRAY: Map<PrimitiveType, Name> = hashMapOf(
|
||||||
PrimitiveType.CHAR to Name.identifier("charArrayOf"),
|
PrimitiveType.BOOLEAN to Name.identifier("booleanArrayOf"),
|
||||||
PrimitiveType.INT to Name.identifier("intArrayOf"),
|
PrimitiveType.CHAR to Name.identifier("charArrayOf"),
|
||||||
PrimitiveType.BYTE to Name.identifier("byteArrayOf"),
|
PrimitiveType.INT to Name.identifier("intArrayOf"),
|
||||||
PrimitiveType.SHORT to Name.identifier("shortArrayOf"),
|
PrimitiveType.BYTE to Name.identifier("byteArrayOf"),
|
||||||
PrimitiveType.FLOAT to Name.identifier("floatArrayOf"),
|
PrimitiveType.SHORT to Name.identifier("shortArrayOf"),
|
||||||
PrimitiveType.LONG to Name.identifier("longArrayOf"),
|
PrimitiveType.FLOAT to Name.identifier("floatArrayOf"),
|
||||||
PrimitiveType.DOUBLE to Name.identifier("doubleArrayOf")
|
PrimitiveType.LONG to Name.identifier("longArrayOf"),
|
||||||
)
|
PrimitiveType.DOUBLE to Name.identifier("doubleArrayOf")
|
||||||
|
)
|
||||||
|
|
||||||
val ARRAY_OF_FUNCTION = Name.identifier("arrayOf")
|
val ARRAY_OF_FUNCTION = Name.identifier("arrayOf")
|
||||||
|
}
|
||||||
|
|
||||||
fun resolveCollectionLiteral(collectionLiteralExpression: KtCollectionLiteralExpression,
|
fun resolveCollectionLiteral(
|
||||||
context: ExpressionTypingContext,
|
collectionLiteralExpression: KtCollectionLiteralExpression,
|
||||||
callResolver: CallResolver,
|
context: ExpressionTypingContext
|
||||||
builtIns: KotlinBuiltIns,
|
|
||||||
languageVersionSettings: LanguageVersionSettings
|
|
||||||
): KotlinTypeInfo {
|
): KotlinTypeInfo {
|
||||||
if (!isInsideAnnotationEntryOrClass(collectionLiteralExpression)) {
|
if (!isInsideAnnotationEntryOrClass(collectionLiteralExpression)) {
|
||||||
context.trace.report(UNSUPPORTED.on(collectionLiteralExpression, "Collection literals outside of annotations"))
|
context.trace.report(UNSUPPORTED.on(collectionLiteralExpression, "Collection literals outside of annotations"))
|
||||||
}
|
}
|
||||||
|
|
||||||
checkSupportsArrayLiterals(collectionLiteralExpression, context, languageVersionSettings)
|
checkSupportsArrayLiterals(collectionLiteralExpression, context)
|
||||||
|
|
||||||
return resolveCollectionLiteralSpecialMethod(collectionLiteralExpression, context, callResolver, builtIns)
|
return resolveCollectionLiteralSpecialMethod(collectionLiteralExpression, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveCollectionLiteralSpecialMethod(
|
private fun resolveCollectionLiteralSpecialMethod(
|
||||||
expression: KtCollectionLiteralExpression,
|
expression: KtCollectionLiteralExpression,
|
||||||
context: ExpressionTypingContext,
|
context: ExpressionTypingContext
|
||||||
callResolver: CallResolver,
|
|
||||||
builtIns: KotlinBuiltIns
|
|
||||||
): KotlinTypeInfo {
|
): KotlinTypeInfo {
|
||||||
val call = CallMaker.makeCallForCollectionLiteral(expression)
|
val call = CallMaker.makeCallForCollectionLiteral(expression)
|
||||||
val functionDescriptor = getFunctionDescriptorForCollectionLiteral(expression, context, builtIns)
|
val callName = getArrayFunctionCallName(context.expectedType)
|
||||||
|
val functionDescriptor = getFunctionDescriptorForCollectionLiteral(expression, callName)
|
||||||
|
if (functionDescriptor == null) {
|
||||||
|
context.trace.report(MISSING_STDLIB.on(
|
||||||
|
expression, "Collection literal call '$callName()' is unresolved"))
|
||||||
|
return noTypeInfo(context)
|
||||||
|
}
|
||||||
|
|
||||||
val resolutionResults = callResolver.resolveCollectionLiteralCallWithGivenDescriptor(context, expression, call, functionDescriptor)
|
val resolutionResults = callResolver.resolveCollectionLiteralCallWithGivenDescriptor(context, expression, call, functionDescriptor)
|
||||||
|
|
||||||
@@ -90,17 +94,13 @@ object CollectionLiteralResolver {
|
|||||||
|
|
||||||
private fun getFunctionDescriptorForCollectionLiteral(
|
private fun getFunctionDescriptorForCollectionLiteral(
|
||||||
expression: KtCollectionLiteralExpression,
|
expression: KtCollectionLiteralExpression,
|
||||||
context: ExpressionTypingContext,
|
callName: Name
|
||||||
builtIns: KotlinBuiltIns
|
): SimpleFunctionDescriptor? {
|
||||||
): SimpleFunctionDescriptor {
|
val memberScopeOfKotlinPackage = module.getPackage(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME).memberScope
|
||||||
val callName = getArrayFunctionCallName(context.expectedType)
|
return memberScopeOfKotlinPackage.getContributedFunctions(callName, KotlinLookupLocation(expression)).singleOrNull()
|
||||||
return builtIns.builtInsPackageScope.getContributedFunctions(callName, KotlinLookupLocation(expression)).single()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkSupportsArrayLiterals(expression: KtCollectionLiteralExpression,
|
private fun checkSupportsArrayLiterals(expression: KtCollectionLiteralExpression, context: ExpressionTypingContext) {
|
||||||
context: ExpressionTypingContext,
|
|
||||||
languageVersionSettings: LanguageVersionSettings
|
|
||||||
) {
|
|
||||||
if (isInsideAnnotationEntryOrClass(expression) &&
|
if (isInsideAnnotationEntryOrClass(expression) &&
|
||||||
!languageVersionSettings.supportsFeature(LanguageFeature.ArrayLiteralsInAnnotations)) {
|
!languageVersionSettings.supportsFeature(LanguageFeature.ArrayLiteralsInAnnotations)) {
|
||||||
context.trace.report(UNSUPPORTED_FEATURE.on(expression, LanguageFeature.ArrayLiteralsInAnnotations to languageVersionSettings))
|
context.trace.report(UNSUPPORTED_FEATURE.on(expression, LanguageFeature.ArrayLiteralsInAnnotations to languageVersionSettings))
|
||||||
|
|||||||
+1
-2
@@ -1423,8 +1423,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
public KotlinTypeInfo visitCollectionLiteralExpression(
|
public KotlinTypeInfo visitCollectionLiteralExpression(
|
||||||
@NotNull KtCollectionLiteralExpression expression, ExpressionTypingContext context
|
@NotNull KtCollectionLiteralExpression expression, ExpressionTypingContext context
|
||||||
) {
|
) {
|
||||||
return CollectionLiteralResolver.INSTANCE.resolveCollectionLiteral(
|
return components.collectionLiteralResolver.resolveCollectionLiteral(expression, context);
|
||||||
expression, context, components.callResolver, components.builtIns, components.languageVersionSettings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+7
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -62,6 +62,7 @@ public class ExpressionTypingComponents {
|
|||||||
/*package*/ LanguageVersionSettings languageVersionSettings;
|
/*package*/ LanguageVersionSettings languageVersionSettings;
|
||||||
/*package*/ Iterable<RttiExpressionChecker> rttiExpressionCheckers;
|
/*package*/ Iterable<RttiExpressionChecker> rttiExpressionCheckers;
|
||||||
/*package*/ WrappedTypeFactory wrappedTypeFactory;
|
/*package*/ WrappedTypeFactory wrappedTypeFactory;
|
||||||
|
/*package*/ CollectionLiteralResolver collectionLiteralResolver;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public void setGlobalContext(@NotNull GlobalContext globalContext) {
|
public void setGlobalContext(@NotNull GlobalContext globalContext) {
|
||||||
@@ -207,4 +208,9 @@ public class ExpressionTypingComponents {
|
|||||||
public void setWrappedTypeFactory(WrappedTypeFactory wrappedTypeFactory) {
|
public void setWrappedTypeFactory(WrappedTypeFactory wrappedTypeFactory) {
|
||||||
this.wrappedTypeFactory = wrappedTypeFactory;
|
this.wrappedTypeFactory = wrappedTypeFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public void setCollectionLiteralResolver(CollectionLiteralResolver collectionLiteralResolver) {
|
||||||
|
this.collectionLiteralResolver = collectionLiteralResolver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user