diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AdditionalCheckerProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AdditionalCheckerProvider.kt index 5ac8b152c88..94e6af59a08 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AdditionalCheckerProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AdditionalCheckerProvider.kt @@ -30,6 +30,7 @@ public abstract class AdditionalCheckerProvider( ) { public val callCheckers: List = DEFAULT_CALL_CHECKERS + additionalCallCheckers + public val additionalTypeCheckers: List = listOf() public object DefaultProvider : AdditionalCheckerProvider(listOf(), listOf()) {} } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java index 69bed6ac94a..79e56562490 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationResolver.java @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver; import org.jetbrains.kotlin.resolve.calls.CallResolver; import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilPackage; +import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker; import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker; import org.jetbrains.kotlin.resolve.calls.checkers.CompositeChecker; import org.jetbrains.kotlin.resolve.calls.context.ContextDependency; @@ -353,7 +354,9 @@ public class AnnotationResolver { SimpleResolutionContext context = new SimpleResolutionContext(trace, JetScope.Empty.INSTANCE$, NO_EXPECTED_TYPE, DataFlowInfo.EMPTY, ContextDependency.INDEPENDENT, - new CompositeChecker(Lists.newArrayList()), StatementFilter.NONE); + new CompositeChecker(Lists.newArrayList()), + new AdditionalTypeChecker.Composite(Lists.newArrayList()), + StatementFilter.NONE); ArgumentTypeResolver.updateNumberType(defaultType, argumentExpression, context); } if (constant != null) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java index 9ed4f32fb67..287f9905b14 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java @@ -219,7 +219,7 @@ public class CallResolver { return resolveFunctionCall( BasicCallResolutionContext.create( trace, scope, call, expectedType, dataFlowInfo, ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED, - expressionTypingServices.getCallChecker(), isAnnotationContext) + expressionTypingServices.getCallChecker(), expressionTypingServices.getAdditionalTypeChecker(), isAnnotationContext) ); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/AdditionalTypeChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/AdditionalTypeChecker.kt new file mode 100644 index 00000000000..8d0b1845249 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/AdditionalTypeChecker.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2015 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.calls.checkers + +import org.jetbrains.kotlin.psi.JetExpression +import org.jetbrains.kotlin.types.JetType +import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext + +public trait AdditionalTypeChecker { + + public class Composite(val checkers: List): AdditionalTypeChecker { + override fun checkType(expression: JetExpression, expressionType: JetType, c: ResolutionContext<*>) { + for (checker in checkers) { + checker.checkType(expression, expressionType, c) + } + } + } + + fun checkType(expression: JetExpression, expressionType: JetType, c: ResolutionContext<*>) +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/BasicCallResolutionContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/BasicCallResolutionContext.java index 7e6027a8e66..83b6d6cd1be 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/BasicCallResolutionContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/BasicCallResolutionContext.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.psi.Call; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.StatementFilter; +import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker; import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker; import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments; import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; @@ -39,12 +40,13 @@ public class BasicCallResolutionContext extends CallResolutionContext @NotNull ResolutionResultsCache resolutionResultsCache, @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments, @NotNull CallChecker callChecker, + @NotNull AdditionalTypeChecker additionalTypeChecker, @NotNull StatementFilter statementFilter, @NotNull ReceiverValue explicitExtensionReceiverForInvoke, boolean isAnnotationContext, boolean collectAllCandidates ) { super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache, - dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates); + dataFlowInfoForArguments, callChecker, additionalTypeChecker, statementFilter, isAnnotationContext, collectAllCandidates); this.candidateCall = candidateCall; this.tracing = tracing; this.explicitExtensionReceiverForInvoke = explicitExtensionReceiverForInvoke; @@ -73,7 +75,7 @@ public final class CallCandidateResolutionContext candidateCall, tracing, trace, context.scope, call, context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments, context.resolutionResultsCache, context.dataFlowInfoForArguments, - context.callChecker, context.statementFilter, explicitExtensionReceiverForInvoke, + context.callChecker, context.additionalTypeChecker, context.statementFilter, explicitExtensionReceiverForInvoke, context.isAnnotationContext, context.collectAllCandidates); } @@ -97,8 +99,8 @@ public final class CallCandidateResolutionContext return new CallCandidateResolutionContext( candidateCall, tracing, context.trace, context.scope, context.call, context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments, context.resolutionResultsCache, - context.dataFlowInfoForArguments, context.callChecker, context.statementFilter, ReceiverValue.NO_RECEIVER, - context.isAnnotationContext, context.collectAllCandidates); + context.dataFlowInfoForArguments, context.callChecker, context.additionalTypeChecker, context.statementFilter, + ReceiverValue.NO_RECEIVER, context.isAnnotationContext, context.collectAllCandidates); } @Override @@ -114,7 +116,7 @@ public final class CallCandidateResolutionContext ) { return new CallCandidateResolutionContext( candidateCall, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, - resolutionResultsCache, dataFlowInfoForArguments, callChecker, statementFilter, + resolutionResultsCache, dataFlowInfoForArguments, callChecker, additionalTypeChecker, statementFilter, explicitExtensionReceiverForInvoke, isAnnotationContext, collectAllCandidates); } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java index e832772496b..97e2ed29c96 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/context/CallResolutionContext.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.psi.Call; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.StatementFilter; +import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker; import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker; import org.jetbrains.kotlin.resolve.calls.model.DataFlowInfoForArgumentsImpl; import org.jetbrains.kotlin.resolve.calls.model.MutableDataFlowInfoForArguments; @@ -48,11 +49,12 @@ public abstract class CallResolutionContext extends C @NotNull ResolutionResultsCache resolutionResultsCache, @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments, @NotNull CallChecker callChecker, + @NotNull AdditionalTypeChecker additionalTypeChecker, @NotNull StatementFilter statementFilter, @NotNull Collection> resolvedCalls, boolean isAnnotationContext, boolean collectAllCandidates ) { super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache, - dataFlowInfoForArguments, callChecker, statementFilter, isAnnotationContext, collectAllCandidates); + dataFlowInfoForArguments, callChecker, additionalTypeChecker, statementFilter, isAnnotationContext, collectAllCandidates); this.lazyCandidates = lazyCandidates; this.resolvedCalls = resolvedCalls; this.tracing = tracing; @@ -77,7 +79,7 @@ public class ResolutionTask extends C context.trace, context.scope, context.call, context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments, context.resolutionResultsCache, context.dataFlowInfoForArguments, - context.callChecker, context.statementFilter, Lists.>newArrayList(), + context.callChecker, context.additionalTypeChecker, context.statementFilter, Lists.>newArrayList(), context.isAnnotationContext, context.collectAllCandidates); } @@ -121,7 +123,7 @@ public class ResolutionTask extends C ) { return new ResolutionTask( lazyCandidates, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, - resolutionResultsCache, dataFlowInfoForArguments, callChecker, statementFilter, resolvedCalls, + resolutionResultsCache, dataFlowInfoForArguments, callChecker, additionalTypeChecker, statementFilter, resolvedCalls, isAnnotationContext, collectAllCandidates); } @@ -132,7 +134,7 @@ public class ResolutionTask extends C public ResolutionTask replaceCall(@NotNull Call newCall) { return new ResolutionTask( lazyCandidates, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments, - resolutionResultsCache, dataFlowInfoForArguments, callChecker, statementFilter, resolvedCalls, + resolutionResultsCache, dataFlowInfoForArguments, callChecker, additionalTypeChecker, statementFilter, resolvedCalls, isAnnotationContext, collectAllCandidates); } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingContext.java index 6bb83660f03..ac1c29c1c55 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/ExpressionTypingContext.java @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.types.expressions; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.StatementFilter; +import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker; import org.jetbrains.kotlin.resolve.calls.context.ContextDependency; import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext; import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCache; @@ -41,14 +42,16 @@ public class ExpressionTypingContext extends ResolutionContext checkers = expressionTypingComponents.additionalCheckerProvider.getCallCheckers(); return new CompositeChecker(checkers); } + + @NotNull + public AdditionalTypeChecker getAdditionalTypeChecker() { + List checkers = expressionTypingComponents.additionalCheckerProvider.getAdditionalTypeCheckers(); + return new AdditionalTypeChecker.Composite(checkers); + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt b/idea/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt index 5367812c587..63768d7467b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt +++ b/idea/src/org/jetbrains/kotlin/idea/completion/ExpectedInfos.kt @@ -69,6 +69,7 @@ import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils +import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker enum class Tail { COMMA @@ -172,6 +173,7 @@ class ExpectedInfos(val bindingContext: BindingContext, val resolutionFacade: Re ContextDependency.INDEPENDENT, CheckValueArgumentsMode.ENABLED, CompositeChecker(listOf()), + AdditionalTypeChecker.Composite(listOf()), false).replaceCollectAllCandidates(true) val callResolver = InjectorForMacros( callElement.getProject(),