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.descriptors.CallableDescriptor;
022    import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
023    import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
024    import org.jetbrains.jet.lang.psi.CallKey;
025    import org.jetbrains.jet.lang.resolve.BindingTrace;
026    import org.jetbrains.jet.lang.resolve.BindingTraceContext;
027    import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
028    import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl;
029    import org.jetbrains.jet.util.slicedmap.BasicWritableSlice;
030    import org.jetbrains.jet.util.slicedmap.Slices;
031    import org.jetbrains.jet.util.slicedmap.WritableSlice;
032    
033    public class ResolutionResultsCache {
034    
035        public static class MemberType<D extends CallableDescriptor> {}
036        public static final MemberType<FunctionDescriptor> FUNCTION_MEMBER_TYPE = new MemberType<FunctionDescriptor>();
037        public static final MemberType<VariableDescriptor> PROPERTY_MEMBER_TYPE = new MemberType<VariableDescriptor>();
038    
039        public static final WritableSlice<CallKey, OverloadResolutionResultsImpl<FunctionDescriptor>> RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice();
040        public static final WritableSlice<CallKey, OverloadResolutionResultsImpl<VariableDescriptor>> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice();
041        public static final WritableSlice<CallKey, DelegatingBindingTrace> TRACE_DELTAS_CACHE = Slices.createSimpleSlice();
042        public static final WritableSlice<CallKey, CallCandidateResolutionContext<FunctionDescriptor>> DEFERRED_COMPUTATION_FOR_CALL = Slices.createSimpleSlice();
043    
044        static {
045            BasicWritableSlice.initSliceDebugNames(ResolutionResultsCache.class);
046        }
047    
048        private final BindingTrace trace = new BindingTraceContext();
049    
050        @NotNull
051        private static <D extends CallableDescriptor> WritableSlice<CallKey, OverloadResolutionResultsImpl<D>> getSliceByMemberType(@NotNull MemberType<D> memberType) {
052            return (WritableSlice<CallKey, OverloadResolutionResultsImpl<D>>)
053                    (memberType == FUNCTION_MEMBER_TYPE ? RESOLUTION_RESULTS_FOR_FUNCTION : RESOLUTION_RESULTS_FOR_PROPERTY);
054        }
055    
056        public <D extends CallableDescriptor> void recordResolutionResults(@NotNull CallKey callKey, @NotNull MemberType<D> memberType, @NotNull OverloadResolutionResultsImpl<D> results) {
057            trace.record(getSliceByMemberType(memberType), callKey, results);
058        }
059    
060        @Nullable
061        public <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> getResolutionResults(@NotNull CallKey callKey, @NotNull MemberType<D> memberType) {
062            return trace.get(getSliceByMemberType(memberType), callKey);
063        }
064    
065        public void recordResolutionTrace(@NotNull CallKey callKey, @NotNull DelegatingBindingTrace delegatingTrace) {
066            trace.record(TRACE_DELTAS_CACHE, callKey, delegatingTrace);
067        }
068    
069        @Nullable
070        public DelegatingBindingTrace getResolutionTrace(@NotNull CallKey callKey) {
071            return trace.get(TRACE_DELTAS_CACHE, callKey);
072        }
073    
074        public <D extends CallableDescriptor> void recordDeferredComputationForCall(
075                @NotNull CallKey callKey,
076                @NotNull CallCandidateResolutionContext<D> deferredComputation,
077                @NotNull MemberType memberType
078        ) {
079            if (memberType == PROPERTY_MEMBER_TYPE) return;
080            trace.record(DEFERRED_COMPUTATION_FOR_CALL, callKey, (CallCandidateResolutionContext<FunctionDescriptor>) deferredComputation);
081        }
082    
083        @Nullable
084        public CallCandidateResolutionContext<FunctionDescriptor> getDeferredComputation(@NotNull CallKey callKey) {
085            return trace.get(DEFERRED_COMPUTATION_FOR_CALL, callKey);
086        }
087    
088        @NotNull
089        public static ResolutionResultsCache create() {
090            return new ResolutionResultsCache();
091        }
092    }