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 com.google.common.collect.Lists;
020 import org.jetbrains.annotations.NotNull;
021 import org.jetbrains.annotations.Nullable;
022 import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
023 import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
024 import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
025 import org.jetbrains.jet.lang.psi.Call;
026 import org.jetbrains.jet.lang.psi.CallKey;
027 import org.jetbrains.jet.lang.psi.JetExpression;
028 import org.jetbrains.jet.lang.resolve.BindingTraceContext;
029 import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
030 import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
031 import org.jetbrains.jet.util.slicedmap.BasicWritableSlice;
032 import org.jetbrains.jet.util.slicedmap.Slices;
033 import org.jetbrains.jet.util.slicedmap.WritableSlice;
034
035 public class ResolutionResultsCacheImpl implements ResolutionResultsCache {
036 public static final WritableSlice<CallKey, OverloadResolutionResultsImpl<FunctionDescriptor>>
037 RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice();
038 public static final WritableSlice<CallKey, OverloadResolutionResultsImpl<VariableDescriptor>> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice();
039 public static final WritableSlice<CallKey, DelegatingBindingTrace> TRACE_DELTAS_CACHE = Slices.createSimpleSlice();
040 public static final WritableSlice<CallKey, CallCandidateResolutionContext<FunctionDescriptor>> DEFERRED_COMPUTATION_FOR_CALL = Slices.createSimpleSlice();
041
042 static {
043 BasicWritableSlice.initSliceDebugNames(ResolutionResultsCacheImpl.class);
044 }
045
046 private final DelegatingBindingTrace trace = new DelegatingBindingTrace(
047 new BindingTraceContext().getBindingContext(), "Internal binding context in resolution results cache");
048
049 @NotNull
050 private static <D extends CallableDescriptor> WritableSlice<CallKey, OverloadResolutionResultsImpl<D>> getSliceByMemberType(@NotNull MemberType<D> memberType) {
051 //noinspection unchecked
052 return (WritableSlice<CallKey, OverloadResolutionResultsImpl<D>>)
053 (memberType == FUNCTION_MEMBER_TYPE ? RESOLUTION_RESULTS_FOR_FUNCTION : RESOLUTION_RESULTS_FOR_PROPERTY);
054 }
055
056 @Override
057 public <D extends CallableDescriptor> void recordResolutionResults(@NotNull CallKey callKey, @NotNull MemberType<D> memberType, @NotNull OverloadResolutionResultsImpl<D> results) {
058 trace.record(getSliceByMemberType(memberType), callKey, results);
059 }
060
061 @Override
062 @Nullable
063 public <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> getResolutionResults(@NotNull CallKey callKey, @NotNull MemberType<D> memberType) {
064 return trace.get(getSliceByMemberType(memberType), callKey);
065 }
066
067 @Override
068 public void recordResolutionTrace(@NotNull CallKey callKey, @NotNull DelegatingBindingTrace delegatingTrace) {
069 trace.record(TRACE_DELTAS_CACHE, callKey, delegatingTrace);
070 }
071
072 @Override
073 @Nullable
074 public DelegatingBindingTrace getResolutionTrace(@NotNull CallKey callKey) {
075 return trace.get(TRACE_DELTAS_CACHE, callKey);
076 }
077
078 @Override
079 public <D extends CallableDescriptor> void recordDeferredComputationForCall(
080 @NotNull CallKey callKey,
081 @NotNull CallCandidateResolutionContext<D> deferredComputation,
082 @NotNull MemberType memberType
083 ) {
084 if (memberType == PROPERTY_MEMBER_TYPE) return;
085 //noinspection unchecked
086 trace.record(DEFERRED_COMPUTATION_FOR_CALL, callKey, (CallCandidateResolutionContext<FunctionDescriptor>) deferredComputation);
087 }
088
089 @Override
090 @Nullable
091 public CallCandidateResolutionContext<FunctionDescriptor> getDeferredComputation(@Nullable JetExpression expression) {
092 if (expression == null) return null;
093 for (Call.CallType callType : Lists
094 .newArrayList(Call.CallType.DEFAULT, Call.CallType.ARRAY_GET_METHOD, Call.CallType.ARRAY_SET_METHOD)) {
095 CallKey callKey = CallKey.create(callType, expression);
096 CallCandidateResolutionContext<FunctionDescriptor> context = trace.get(DEFERRED_COMPUTATION_FOR_CALL, callKey);
097 if (context != null) {
098 return context;
099 }
100 }
101 return null;
102 }
103
104 @NotNull
105 public static ResolutionResultsCache create() {
106 return new ResolutionResultsCacheImpl();
107 }
108
109 /*package*/ void addData(@NotNull ResolutionResultsCacheImpl cache) {
110 cache.trace.addAllMyDataTo(this.trace);
111 }
112 }