001    /*
002     * Copyright 2010-2015 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.types.expressions;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.kotlin.resolve.AdditionalCheckerProvider;
022    import org.jetbrains.kotlin.resolve.BindingTrace;
023    import org.jetbrains.kotlin.resolve.StatementFilter;
024    import org.jetbrains.kotlin.resolve.calls.checkers.AdditionalTypeChecker;
025    import org.jetbrains.kotlin.resolve.calls.context.ContextDependency;
026    import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
027    import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCache;
028    import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCacheImpl;
029    import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker;
030    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
031    import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker;
032    import org.jetbrains.kotlin.resolve.scopes.JetScope;
033    import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator;
034    import org.jetbrains.kotlin.types.JetType;
035    
036    public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingContext> {
037    
038        @NotNull
039        public static ExpressionTypingContext newContext(
040                @NotNull AdditionalCheckerProvider additionalCheckerProvider,
041                @NotNull BindingTrace trace,
042                @NotNull JetScope scope,
043                @NotNull DataFlowInfo dataFlowInfo,
044                @NotNull JetType expectedType
045        ) {
046            return newContext(additionalCheckerProvider, trace, scope, dataFlowInfo, expectedType, null);
047        }
048    
049        @NotNull
050        public static ExpressionTypingContext newContext(
051                @NotNull AdditionalCheckerProvider additionalCheckerProvider,
052                @NotNull BindingTrace trace,
053                @NotNull JetScope scope,
054                @NotNull DataFlowInfo dataFlowInfo,
055                @NotNull JetType expectedType,
056                @Nullable CallChecker callChecker
057        ) {
058            return newContext(trace, scope, dataFlowInfo, expectedType,
059                              ContextDependency.INDEPENDENT, new ResolutionResultsCacheImpl(),
060                              callChecker != null ? callChecker : additionalCheckerProvider.getCallChecker(),
061                              additionalCheckerProvider.getSymbolUsageValidator(),
062                              additionalCheckerProvider.getTypeChecker(),
063                              StatementFilter.NONE, false);
064        }
065    
066        @NotNull
067        public static ExpressionTypingContext newContext(@NotNull ResolutionContext context) {
068            return new ExpressionTypingContext(
069                    context.trace, context.scope, context.dataFlowInfo, context.expectedType,
070                    context.contextDependency, context.resolutionResultsCache,
071                    context.callChecker, context.symbolUsageValidator, context.additionalTypeChecker,
072                    context.statementFilter,
073                    context.isAnnotationContext, context.collectAllCandidates, context.insideCallChain
074            );
075        }
076    
077        @NotNull
078        public static ExpressionTypingContext newContext(
079                @NotNull BindingTrace trace,
080                @NotNull JetScope scope,
081                @NotNull DataFlowInfo dataFlowInfo,
082                @NotNull JetType expectedType,
083                @NotNull ContextDependency contextDependency,
084                @NotNull ResolutionResultsCache resolutionResultsCache,
085                @NotNull CallChecker callChecker,
086                @NotNull SymbolUsageValidator symbolUsageValidator,
087                @NotNull AdditionalTypeChecker additionalTypeChecker,
088                @NotNull StatementFilter statementFilter,
089                boolean isAnnotationContext
090        ) {
091            return new ExpressionTypingContext(
092                    trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, callChecker, symbolUsageValidator,
093                    additionalTypeChecker,
094                    statementFilter, isAnnotationContext, false, false);
095        }
096    
097        private CompileTimeConstantChecker compileTimeConstantChecker;
098    
099        private ExpressionTypingContext(
100                @NotNull BindingTrace trace,
101                @NotNull JetScope scope,
102                @NotNull DataFlowInfo dataFlowInfo,
103                @NotNull JetType expectedType,
104                @NotNull ContextDependency contextDependency,
105                @NotNull ResolutionResultsCache resolutionResultsCache,
106                @NotNull CallChecker callChecker,
107                @NotNull SymbolUsageValidator symbolUsageValidator,
108                @NotNull AdditionalTypeChecker additionalTypeChecker,
109                @NotNull StatementFilter statementFilter,
110                boolean isAnnotationContext,
111                boolean collectAllCandidates,
112                boolean insideSafeCallChain
113        ) {
114            super(trace, scope, expectedType, dataFlowInfo, contextDependency, resolutionResultsCache,
115                  callChecker, symbolUsageValidator, additionalTypeChecker,
116                  statementFilter, isAnnotationContext, collectAllCandidates, insideSafeCallChain);
117        }
118    
119        @Override
120        protected ExpressionTypingContext create(
121                @NotNull BindingTrace trace,
122                @NotNull JetScope scope,
123                @NotNull DataFlowInfo dataFlowInfo,
124                @NotNull JetType expectedType,
125                @NotNull ContextDependency contextDependency,
126                @NotNull ResolutionResultsCache resolutionResultsCache,
127                @NotNull StatementFilter statementFilter,
128                boolean collectAllCandidates,
129                boolean insideSafeCallChain
130        ) {
131            return new ExpressionTypingContext(trace, scope, dataFlowInfo,
132                                               expectedType, contextDependency, resolutionResultsCache,
133                                               callChecker, symbolUsageValidator, additionalTypeChecker,
134                                               statementFilter, isAnnotationContext, collectAllCandidates, insideSafeCallChain);
135        }
136    
137    ///////////// LAZY ACCESSORS
138    
139        public CompileTimeConstantChecker getCompileTimeConstantChecker() {
140            if (compileTimeConstantChecker == null) {
141                compileTimeConstantChecker = new CompileTimeConstantChecker(trace, false);
142            }
143            return compileTimeConstantChecker;
144        }
145    }