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.resolve.calls.context;
018
019import org.jetbrains.annotations.NotNull;
020import org.jetbrains.annotations.Nullable;
021import org.jetbrains.jet.lang.resolve.BindingTrace;
022import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
023import org.jetbrains.jet.lang.resolve.scopes.JetScope;
024import org.jetbrains.jet.lang.types.JetType;
025import org.jetbrains.jet.lang.types.TypeUtils;
026
027public abstract class ResolutionContext<Context extends ResolutionContext> {
028    public final BindingTrace trace;
029    public final JetScope scope;
030    public final JetType expectedType;
031    public final DataFlowInfo dataFlowInfo;
032    public final ExpressionPosition expressionPosition;
033
034    protected ResolutionContext(
035            @NotNull BindingTrace trace,
036            @NotNull JetScope scope,
037            @NotNull JetType expectedType,
038            @NotNull DataFlowInfo dataFlowInfo,
039            @NotNull ExpressionPosition expressionPosition
040    ) {
041        this.trace = trace;
042        this.scope = scope;
043        this.expectedType = expectedType;
044        this.dataFlowInfo = dataFlowInfo;
045        this.expressionPosition = expressionPosition;
046    }
047
048    protected abstract Context create(
049            @NotNull BindingTrace trace,
050            @NotNull JetScope scope,
051            @NotNull DataFlowInfo dataFlowInfo,
052            @NotNull JetType expectedType,
053            @NotNull ExpressionPosition expressionPosition
054    );
055    
056    protected abstract Context self();
057    
058    public Context replaceBindingTrace(@NotNull BindingTrace trace) {
059        if (this.trace == trace) return self();
060        return create(trace, scope, dataFlowInfo, expectedType, expressionPosition);
061    }
062    
063    @NotNull
064    public Context replaceExpressionPosition(@NotNull ExpressionPosition expressionPosition) {
065        if (expressionPosition == this.expressionPosition) return self();
066        return create(trace, scope, dataFlowInfo, expectedType, expressionPosition);
067    }
068
069    @NotNull
070    public Context replaceDataFlowInfo(@NotNull DataFlowInfo newDataFlowInfo) {
071        if (newDataFlowInfo == dataFlowInfo) return self();
072        return create(trace, scope, newDataFlowInfo, expectedType, expressionPosition);
073    }
074
075    @NotNull
076    public Context replaceExpectedType(@Nullable JetType newExpectedType) {
077        if (newExpectedType == null) return replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE);
078        if (expectedType == newExpectedType) return self();
079        return create(trace, scope, dataFlowInfo, newExpectedType, expressionPosition);
080    }
081
082    @NotNull
083    public Context replaceScope(@NotNull JetScope newScope) {
084        if (newScope == scope) return self();
085        return create(trace, newScope, dataFlowInfo, expectedType, expressionPosition);
086    }
087}