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.resolve.calls.context;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
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.scopes.JetScope;
025 import org.jetbrains.jet.lang.types.JetType;
026 import org.jetbrains.jet.lang.types.TypeUtils;
027
028 public abstract class ResolutionContext<Context extends ResolutionContext<Context>> {
029 @NotNull
030 public final BindingTrace trace;
031 @NotNull
032 public final JetScope scope;
033 @NotNull
034 public final JetType expectedType;
035 @NotNull
036 public final DataFlowInfo dataFlowInfo;
037 @NotNull
038 public final ContextDependency contextDependency;
039 @NotNull
040 public final ResolutionResultsCache resolutionResultsCache;
041 @NotNull
042 public final CallResolverExtension callResolverExtension;
043
044 public final boolean isAnnotationContext;
045
046 public final boolean collectAllCandidates;
047
048 protected ResolutionContext(
049 @NotNull BindingTrace trace,
050 @NotNull JetScope scope,
051 @NotNull JetType expectedType,
052 @NotNull DataFlowInfo dataFlowInfo,
053 @NotNull ContextDependency contextDependency,
054 @NotNull ResolutionResultsCache resolutionResultsCache,
055 @NotNull CallResolverExtension callResolverExtension,
056 boolean isAnnotationContext,
057 boolean collectAllCandidates
058 ) {
059 this.trace = trace;
060 this.scope = scope;
061 this.expectedType = expectedType;
062 this.dataFlowInfo = dataFlowInfo;
063 this.contextDependency = contextDependency;
064 this.resolutionResultsCache = resolutionResultsCache;
065 this.callResolverExtension = callResolverExtension;
066 this.isAnnotationContext = isAnnotationContext;
067 this.collectAllCandidates = collectAllCandidates;
068 }
069
070 protected abstract Context create(
071 @NotNull BindingTrace trace,
072 @NotNull JetScope scope,
073 @NotNull DataFlowInfo dataFlowInfo,
074 @NotNull JetType expectedType,
075 @NotNull ContextDependency contextDependency,
076 @NotNull ResolutionResultsCache resolutionResultsCache,
077 boolean collectAllCandidates
078 );
079
080 @NotNull
081 private Context self() {
082 //noinspection unchecked
083 return (Context) this;
084 }
085
086 @NotNull
087 public Context replaceBindingTrace(@NotNull BindingTrace trace) {
088 if (this.trace == trace) return self();
089 return create(trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, collectAllCandidates);
090 }
091
092 @NotNull
093 public Context replaceDataFlowInfo(@NotNull DataFlowInfo newDataFlowInfo) {
094 if (newDataFlowInfo == dataFlowInfo) return self();
095 return create(trace, scope, newDataFlowInfo, expectedType, contextDependency, resolutionResultsCache, collectAllCandidates);
096 }
097
098 @NotNull
099 public Context replaceExpectedType(@Nullable JetType newExpectedType) {
100 if (newExpectedType == null) return replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE);
101 if (expectedType == newExpectedType) return self();
102 return create(trace, scope, dataFlowInfo, newExpectedType, contextDependency, resolutionResultsCache, collectAllCandidates);
103 }
104
105 @NotNull
106 public Context replaceScope(@NotNull JetScope newScope) {
107 if (newScope == scope) return self();
108 return create(trace, newScope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, collectAllCandidates);
109 }
110
111 @NotNull
112 public Context replaceContextDependency(@NotNull ContextDependency newContextDependency) {
113 if (newContextDependency == contextDependency) return self();
114 return create(trace, scope, dataFlowInfo, expectedType, newContextDependency, resolutionResultsCache, collectAllCandidates);
115 }
116
117 @NotNull
118 public Context replaceResolutionResultsCache(@NotNull ResolutionResultsCache newResolutionResultsCache) {
119 if (newResolutionResultsCache == resolutionResultsCache) return self();
120 return create(trace, scope, dataFlowInfo, expectedType, contextDependency, newResolutionResultsCache, collectAllCandidates);
121 }
122
123 @NotNull
124 public Context replaceTraceAndCache(@NotNull TemporaryTraceAndCache traceAndCache) {
125 return replaceBindingTrace(traceAndCache.trace).replaceResolutionResultsCache(traceAndCache.cache);
126 }
127
128 @NotNull
129 public Context replaceCollectAllCandidates(boolean newCollectAllCandidates) {
130 return create(trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, newCollectAllCandidates);
131 }
132 }