diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index d9927b4584c..b955a1e277c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -66,6 +66,8 @@ public interface Errors { DiagnosticFactory1> UNSUPPORTED_FEATURE = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 EXCEPTION_FROM_ANALYZER = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1 MISSING_STDLIB = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1> EXPERIMENTAL_FEATURE_WARNING = DiagnosticFactory1.create(WARNING); DiagnosticFactory1> EXPERIMENTAL_FEATURE_ERROR = DiagnosticFactory1.create(ERROR); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 0e87d83f9ed..d745858b040 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -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); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CollectionLiteralResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CollectionLiteralResolver.kt index 8cdd7dbe9dc..20a4c91e102 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CollectionLiteralResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CollectionLiteralResolver.kt @@ -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 = 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 = 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)) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index bdffb2560a6..a29c38538cc 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -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 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java index 1b26644adbc..c2fcad22b48 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingComponents.java @@ -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 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; + } }