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