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.resolve.calls.context; 018 019 import org.jetbrains.annotations.NotNull; 020 import org.jetbrains.annotations.Nullable; 021 import org.jetbrains.kotlin.resolve.BindingTrace; 022 import org.jetbrains.kotlin.resolve.StatementFilter; 023 import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker; 024 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo; 025 import org.jetbrains.kotlin.resolve.scopes.LexicalScope; 026 import org.jetbrains.kotlin.types.KotlinType; 027 import org.jetbrains.kotlin.types.TypeUtils; 028 029 /** 030 * This class together with its descendants is intended to transfer data flow analysis information 031 * in top-down direction, from AST parents to children. 032 * 033 * NB: all descendants must be immutable! 034 */ 035 public abstract class ResolutionContext<Context extends ResolutionContext<Context>> { 036 @NotNull 037 public final BindingTrace trace; 038 @NotNull 039 public final LexicalScope scope; 040 @NotNull 041 public final KotlinType expectedType; 042 @NotNull 043 public final DataFlowInfo dataFlowInfo; 044 @NotNull 045 public final ContextDependency contextDependency; 046 @NotNull 047 public final ResolutionResultsCache resolutionResultsCache; 048 @NotNull 049 public final CallChecker callChecker; 050 @NotNull 051 public final StatementFilter statementFilter; 052 053 public final boolean isAnnotationContext; 054 055 public final boolean isDebuggerContext; 056 057 public final boolean collectAllCandidates; 058 059 @NotNull 060 public final CallPosition callPosition; 061 062 protected ResolutionContext( 063 @NotNull BindingTrace trace, 064 @NotNull LexicalScope scope, 065 @NotNull KotlinType expectedType, 066 @NotNull DataFlowInfo dataFlowInfo, 067 @NotNull ContextDependency contextDependency, 068 @NotNull ResolutionResultsCache resolutionResultsCache, 069 @NotNull CallChecker callChecker, 070 @NotNull StatementFilter statementFilter, 071 boolean isAnnotationContext, 072 boolean isDebuggerContext, 073 boolean collectAllCandidates, 074 @NotNull CallPosition callPosition 075 ) { 076 this.trace = trace; 077 this.scope = scope; 078 this.expectedType = expectedType; 079 this.dataFlowInfo = dataFlowInfo; 080 this.contextDependency = contextDependency; 081 this.resolutionResultsCache = resolutionResultsCache; 082 this.callChecker = callChecker; 083 this.statementFilter = statementFilter; 084 this.isAnnotationContext = isAnnotationContext; 085 this.isDebuggerContext = isDebuggerContext; 086 this.collectAllCandidates = collectAllCandidates; 087 this.callPosition = callPosition; 088 } 089 090 protected abstract Context create( 091 @NotNull BindingTrace trace, 092 @NotNull LexicalScope scope, 093 @NotNull DataFlowInfo dataFlowInfo, 094 @NotNull KotlinType expectedType, 095 @NotNull ContextDependency contextDependency, 096 @NotNull ResolutionResultsCache resolutionResultsCache, 097 @NotNull StatementFilter statementFilter, 098 boolean collectAllCandidates, 099 @NotNull CallPosition callPosition 100 ); 101 102 @NotNull 103 private Context self() { 104 //noinspection unchecked 105 return (Context) this; 106 } 107 108 @NotNull 109 public Context replaceBindingTrace(@NotNull BindingTrace trace) { 110 if (this.trace == trace) return self(); 111 return create(trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, statementFilter, 112 collectAllCandidates, callPosition); 113 } 114 115 @NotNull 116 public Context replaceDataFlowInfo(@NotNull DataFlowInfo newDataFlowInfo) { 117 if (newDataFlowInfo == dataFlowInfo) return self(); 118 return create(trace, scope, newDataFlowInfo, expectedType, contextDependency, resolutionResultsCache, statementFilter, 119 collectAllCandidates, callPosition); 120 } 121 122 @NotNull 123 public Context replaceExpectedType(@Nullable KotlinType newExpectedType) { 124 if (newExpectedType == null) return replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); 125 if (expectedType == newExpectedType) return self(); 126 return create(trace, scope, dataFlowInfo, newExpectedType, contextDependency, resolutionResultsCache, statementFilter, 127 collectAllCandidates, callPosition); 128 } 129 130 @NotNull 131 public Context replaceScope(@NotNull LexicalScope newScope) { 132 if (newScope == scope) return self(); 133 return create(trace, newScope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, statementFilter, 134 collectAllCandidates, callPosition); 135 } 136 137 @NotNull 138 public Context replaceContextDependency(@NotNull ContextDependency newContextDependency) { 139 if (newContextDependency == contextDependency) return self(); 140 return create(trace, scope, dataFlowInfo, expectedType, newContextDependency, resolutionResultsCache, statementFilter, 141 collectAllCandidates, callPosition); 142 } 143 144 @NotNull 145 public Context replaceResolutionResultsCache(@NotNull ResolutionResultsCache newResolutionResultsCache) { 146 if (newResolutionResultsCache == resolutionResultsCache) return self(); 147 return create(trace, scope, dataFlowInfo, expectedType, contextDependency, newResolutionResultsCache, statementFilter, 148 collectAllCandidates, callPosition); 149 } 150 151 @NotNull 152 public Context replaceTraceAndCache(@NotNull TemporaryTraceAndCache traceAndCache) { 153 return replaceBindingTrace(traceAndCache.trace).replaceResolutionResultsCache(traceAndCache.cache); 154 } 155 156 @NotNull 157 public Context replaceCollectAllCandidates(boolean newCollectAllCandidates) { 158 return create(trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, statementFilter, 159 newCollectAllCandidates, callPosition); 160 } 161 162 @NotNull 163 public Context replaceStatementFilter(@NotNull StatementFilter statementFilter) { 164 return create(trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, statementFilter, 165 collectAllCandidates, callPosition); 166 } 167 168 @NotNull 169 public Context replaceCallPosition(@NotNull CallPosition callPosition) { 170 return create(trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, statementFilter, 171 collectAllCandidates, callPosition); 172 } 173 }