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;
018    
019    import com.intellij.util.SmartFMap;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.kotlin.diagnostics.Diagnostic;
023    import org.jetbrains.kotlin.psi.KtExpression;
024    import org.jetbrains.kotlin.types.KotlinType;
025    import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice;
026    import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
027    
028    import java.util.Collection;
029    
030    public class ObservableBindingTrace implements BindingTrace {
031        public interface RecordHandler<K, V> {
032    
033            void handleRecord(WritableSlice<K, V> slice, K key, V value);
034        }
035    
036        private final BindingTrace originalTrace;
037    
038        private SmartFMap<WritableSlice, RecordHandler> handlers = SmartFMap.emptyMap();
039    
040        public ObservableBindingTrace(BindingTrace originalTrace) {
041            this.originalTrace = originalTrace;
042        }
043        @Override
044        public void report(@NotNull Diagnostic diagnostic) {
045            originalTrace.report(diagnostic);
046        }
047    
048        @NotNull
049        @Override
050        public BindingContext getBindingContext() {
051            return originalTrace.getBindingContext();
052        }
053    
054        @Override
055        public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
056            originalTrace.record(slice, key, value);
057            RecordHandler recordHandler = handlers.get(slice);
058            if (recordHandler != null) {
059                recordHandler.handleRecord(slice, key, value);
060            }
061        }
062    
063        @Override
064        public <K> void record(WritableSlice<K, Boolean> slice, K key) {
065            record(slice, key, true);
066        }
067    
068        @Override
069        public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
070            return originalTrace.get(slice, key);
071        }
072    
073        @Override
074        @NotNull
075        public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
076            return originalTrace.getKeys(slice);
077        }
078    
079        @Nullable
080        @Override
081        public KotlinType getType(@NotNull KtExpression expression) {
082            return originalTrace.getType(expression);
083        }
084    
085        @Override
086        public void recordType(@NotNull KtExpression expression, @Nullable KotlinType type) {
087            originalTrace.recordType(expression, type);
088        }
089    
090        public <K, V> ObservableBindingTrace addHandler(@NotNull WritableSlice<K, V> slice, @NotNull RecordHandler<K, V> handler) {
091            handlers = handlers.plus(slice, handler);
092            return this;
093        }
094        
095    }