Avoid getting descriptors for collection literals from built-ins scope

#KT-18845 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2017-07-05 18:08:46 +03:00
parent 1de685949b
commit daa8521729
5 changed files with 45 additions and 37 deletions
@@ -66,6 +66,8 @@ public interface Errors {
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> UNSUPPORTED_FEATURE = 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_ERROR = DiagnosticFactory1.create(ERROR);
@@ -578,6 +578,7 @@ public class DefaultErrorMessages {
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(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(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);
@@ -21,9 +21,9 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED
import org.jetbrains.kotlin.diagnostics.Errors.UNSUPPORTED_FEATURE
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
import org.jetbrains.kotlin.name.Name
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.noTypeInfo
object CollectionLiteralResolver {
val PRIMITIVE_TYPE_TO_ARRAY: Map<PrimitiveType, Name> = hashMapOf(
PrimitiveType.BOOLEAN to Name.identifier("booleanArrayOf"),
PrimitiveType.CHAR to Name.identifier("charArrayOf"),
PrimitiveType.INT to Name.identifier("intArrayOf"),
PrimitiveType.BYTE to Name.identifier("byteArrayOf"),
PrimitiveType.SHORT to Name.identifier("shortArrayOf"),
PrimitiveType.FLOAT to Name.identifier("floatArrayOf"),
PrimitiveType.LONG to Name.identifier("longArrayOf"),
PrimitiveType.DOUBLE to Name.identifier("doubleArrayOf")
)
class CollectionLiteralResolver(val module: ModuleDescriptor, val callResolver: CallResolver, val languageVersionSettings: LanguageVersionSettings) {
companion object {
val PRIMITIVE_TYPE_TO_ARRAY: Map<PrimitiveType, Name> = hashMapOf(
PrimitiveType.BOOLEAN to Name.identifier("booleanArrayOf"),
PrimitiveType.CHAR to Name.identifier("charArrayOf"),
PrimitiveType.INT to Name.identifier("intArrayOf"),
PrimitiveType.BYTE to Name.identifier("byteArrayOf"),
PrimitiveType.SHORT to Name.identifier("shortArrayOf"),
PrimitiveType.FLOAT to Name.identifier("floatArrayOf"),
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,
context: ExpressionTypingContext,
callResolver: CallResolver,
builtIns: KotlinBuiltIns,
languageVersionSettings: LanguageVersionSettings
fun resolveCollectionLiteral(
collectionLiteralExpression: KtCollectionLiteralExpression,
context: ExpressionTypingContext
): KotlinTypeInfo {
if (!isInsideAnnotationEntryOrClass(collectionLiteralExpression)) {
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(
expression: KtCollectionLiteralExpression,
context: ExpressionTypingContext,
callResolver: CallResolver,
builtIns: KotlinBuiltIns
context: ExpressionTypingContext
): KotlinTypeInfo {
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)
@@ -90,17 +94,13 @@ object CollectionLiteralResolver {
private fun getFunctionDescriptorForCollectionLiteral(
expression: KtCollectionLiteralExpression,
context: ExpressionTypingContext,
builtIns: KotlinBuiltIns
): SimpleFunctionDescriptor {
val callName = getArrayFunctionCallName(context.expectedType)
return builtIns.builtInsPackageScope.getContributedFunctions(callName, KotlinLookupLocation(expression)).single()
callName: Name
): SimpleFunctionDescriptor? {
val memberScopeOfKotlinPackage = module.getPackage(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME).memberScope
return memberScopeOfKotlinPackage.getContributedFunctions(callName, KotlinLookupLocation(expression)).singleOrNull()
}
private fun checkSupportsArrayLiterals(expression: KtCollectionLiteralExpression,
context: ExpressionTypingContext,
languageVersionSettings: LanguageVersionSettings
) {
private fun checkSupportsArrayLiterals(expression: KtCollectionLiteralExpression, context: ExpressionTypingContext) {
if (isInsideAnnotationEntryOrClass(expression) &&
!languageVersionSettings.supportsFeature(LanguageFeature.ArrayLiteralsInAnnotations)) {
context.trace.report(UNSUPPORTED_FEATURE.on(expression, LanguageFeature.ArrayLiteralsInAnnotations to languageVersionSettings))
@@ -1423,8 +1423,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
public KotlinTypeInfo visitCollectionLiteralExpression(
@NotNull KtCollectionLiteralExpression expression, ExpressionTypingContext context
) {
return CollectionLiteralResolver.INSTANCE.resolveCollectionLiteral(
expression, context, components.callResolver, components.builtIns, components.languageVersionSettings);
return components.collectionLiteralResolver.resolveCollectionLiteral(expression, context);
}
@Override
@@ -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");
* you may not use this file except in compliance with the License.
@@ -62,6 +62,7 @@ public class ExpressionTypingComponents {
/*package*/ LanguageVersionSettings languageVersionSettings;
/*package*/ Iterable<RttiExpressionChecker> rttiExpressionCheckers;
/*package*/ WrappedTypeFactory wrappedTypeFactory;
/*package*/ CollectionLiteralResolver collectionLiteralResolver;
@Inject
public void setGlobalContext(@NotNull GlobalContext globalContext) {
@@ -207,4 +208,9 @@ public class ExpressionTypingComponents {
public void setWrappedTypeFactory(WrappedTypeFactory wrappedTypeFactory) {
this.wrappedTypeFactory = wrappedTypeFactory;
}
@Inject
public void setCollectionLiteralResolver(CollectionLiteralResolver collectionLiteralResolver) {
this.collectionLiteralResolver = collectionLiteralResolver;
}
}