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
017package org.jetbrains.jet.lang.types.expressions;
018
019import org.jetbrains.annotations.NotNull;
020import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
021import org.jetbrains.jet.lang.psi.Call;
022import org.jetbrains.jet.lang.psi.JetReferenceExpression;
023import org.jetbrains.jet.lang.resolve.BindingTrace;
024import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
025import org.jetbrains.jet.lang.resolve.calls.context.*;
026import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
027import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
028import org.jetbrains.jet.lang.resolve.name.Name;
029import org.jetbrains.jet.lang.resolve.scopes.JetScope;
030import org.jetbrains.jet.lang.types.JetType;
031
032public 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            @NotNull ExpressionPosition expressionPosition) {
042        return newContext(expressionTypingServices, new LabelResolver(), trace, scope, dataFlowInfo, expectedType, expressionPosition);
043    }
044
045    @NotNull
046    public static ExpressionTypingContext newContext(
047            @NotNull ExpressionTypingServices expressionTypingServices,
048            @NotNull LabelResolver labelResolver,
049            @NotNull BindingTrace trace,
050            @NotNull JetScope scope,
051            @NotNull DataFlowInfo dataFlowInfo,
052            @NotNull JetType expectedType,
053            @NotNull ExpressionPosition expressionPosition) {
054        return new ExpressionTypingContext(expressionTypingServices, 
055                                           labelResolver, trace, scope, dataFlowInfo, expectedType, expressionPosition);
056    }
057
058    public final ExpressionTypingServices expressionTypingServices;
059
060    public final LabelResolver labelResolver;
061
062    private CompileTimeConstantResolver compileTimeConstantResolver;
063
064    private ExpressionTypingContext(
065            @NotNull ExpressionTypingServices expressionTypingServices,
066            @NotNull LabelResolver labelResolver,
067            @NotNull BindingTrace trace,
068            @NotNull JetScope scope,
069            @NotNull DataFlowInfo dataFlowInfo,
070            @NotNull JetType expectedType,
071            @NotNull ExpressionPosition expressionPosition) {
072        super(trace, scope, expectedType, dataFlowInfo, expressionPosition);
073        this.expressionTypingServices = expressionTypingServices;
074        this.labelResolver = labelResolver;
075    }
076
077    @Override
078    protected ExpressionTypingContext create(
079            @NotNull BindingTrace trace,
080            @NotNull JetScope scope,
081            @NotNull DataFlowInfo dataFlowInfo,
082            @NotNull JetType expectedType,
083            @NotNull ExpressionPosition expressionPosition
084    ) {
085        return new ExpressionTypingContext(expressionTypingServices, labelResolver, trace, scope, dataFlowInfo, expectedType, expressionPosition);
086    }
087
088    @Override
089    protected ExpressionTypingContext self() {
090        return this;
091    }
092
093///////////// LAZY ACCESSORS
094
095    public CompileTimeConstantResolver getCompileTimeConstantResolver() {
096        if (compileTimeConstantResolver == null) {
097            compileTimeConstantResolver = new CompileTimeConstantResolver();
098        }
099        return compileTimeConstantResolver;
100    }
101
102////////// Call resolution utilities
103
104    @NotNull
105    public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull Name name) {
106        return expressionTypingServices.getCallResolver().resolveCallWithGivenName(
107                BasicCallResolutionContext.create(this, call, ResolveMode.TOP_LEVEL_CALL,
108                                                  CheckValueArgumentsMode.ENABLED, ResolutionResultsCache.create()),
109                functionReference,
110                name
111        );
112    }
113}