001    /*
002     * Copyright 2010-2013 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.jet.lang.types.expressions;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
021    import org.jetbrains.jet.lang.resolve.BindingTrace;
022    import org.jetbrains.jet.lang.resolve.calls.CallResolverExtension;
023    import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
024    import org.jetbrains.jet.lang.resolve.calls.context.ContextDependency;
025    import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext;
026    import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCache;
027    import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCacheImpl;
028    import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantChecker;
029    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
030    import org.jetbrains.jet.lang.types.JetType;
031    
032    public class ExpressionTypingContext extends ResolutionContext<ExpressionTypingContext> {
033    
034        @NotNull
035        public static ExpressionTypingContext newContext(
036                @NotNull ExpressionTypingServices expressionTypingServices,
037                @NotNull BindingTrace trace,
038                @NotNull JetScope scope,
039                @NotNull DataFlowInfo dataFlowInfo,
040                @NotNull JetType expectedType
041        ) {
042            return newContext(trace, scope, dataFlowInfo, expectedType,
043                              ContextDependency.INDEPENDENT, new ResolutionResultsCacheImpl(), LabelResolver.create(),
044                              expressionTypingServices.createExtension(scope, false), false);
045        }
046    
047        @NotNull
048        public static ExpressionTypingContext newContext(@NotNull ResolutionContext context) {
049            return new ExpressionTypingContext(
050                    context.labelResolver, context.trace, context.scope, context.scope.getContainingDeclaration(),
051                    context.dataFlowInfo, context.expectedType, context.contextDependency, context.resolutionResultsCache,
052                    context.callResolverExtension, context.isAnnotationContext, context.collectAllCandidates
053            );
054        }
055    
056        @NotNull
057        public static ExpressionTypingContext newContext(
058                @NotNull BindingTrace trace,
059                @NotNull JetScope scope,
060                @NotNull DataFlowInfo dataFlowInfo,
061                @NotNull JetType expectedType,
062                @NotNull ContextDependency contextDependency,
063                @NotNull ResolutionResultsCache resolutionResultsCache,
064                @NotNull LabelResolver labelResolver,
065                @NotNull CallResolverExtension callResolverExtension,
066                boolean isAnnotationContext
067        ) {
068            return new ExpressionTypingContext(
069                    labelResolver, trace, scope, scope.getContainingDeclaration(), dataFlowInfo, expectedType, contextDependency,
070                    resolutionResultsCache, callResolverExtension, isAnnotationContext, false);
071        }
072    
073        public final DeclarationDescriptor containingDeclaration;
074        private CompileTimeConstantChecker compileTimeConstantChecker;
075    
076        private ExpressionTypingContext(
077                @NotNull LabelResolver labelResolver,
078                @NotNull BindingTrace trace,
079                @NotNull JetScope scope,
080                @NotNull DeclarationDescriptor containingDeclaration,
081                @NotNull DataFlowInfo dataFlowInfo,
082                @NotNull JetType expectedType,
083                @NotNull ContextDependency contextDependency,
084                @NotNull ResolutionResultsCache resolutionResultsCache,
085                @NotNull CallResolverExtension callResolverExtension,
086                boolean isAnnotationContext,
087                boolean collectAllCandidates
088        ) {
089            super(trace, scope, expectedType, dataFlowInfo, contextDependency, resolutionResultsCache, labelResolver, callResolverExtension,
090                  isAnnotationContext, collectAllCandidates);
091            this.containingDeclaration = containingDeclaration;
092        }
093    
094        @Override
095        protected ExpressionTypingContext create(
096                @NotNull BindingTrace trace,
097                @NotNull JetScope scope,
098                @NotNull DataFlowInfo dataFlowInfo,
099                @NotNull JetType expectedType,
100                @NotNull ContextDependency contextDependency,
101                @NotNull ResolutionResultsCache resolutionResultsCache,
102                @NotNull LabelResolver labelResolver,
103                boolean collectAllCandidates
104        ) {
105            return new ExpressionTypingContext(this.labelResolver, trace, scope, containingDeclaration, dataFlowInfo,
106                                               expectedType, contextDependency, resolutionResultsCache, callResolverExtension,
107                                               isAnnotationContext, collectAllCandidates);
108        }
109    
110    ///////////// LAZY ACCESSORS
111    
112        public CompileTimeConstantChecker getCompileTimeConstantChecker() {
113            if (compileTimeConstantChecker == null) {
114                compileTimeConstantChecker = new CompileTimeConstantChecker(trace, false);
115            }
116            return compileTimeConstantChecker;
117        }
118    }