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;
018    
019    import com.google.common.collect.ImmutableMap;
020    import com.google.common.collect.Lists;
021    import org.jetbrains.annotations.NotNull;
022    import org.jetbrains.annotations.TestOnly;
023    import org.jetbrains.jet.lang.diagnostics.Diagnostic;
024    import org.jetbrains.jet.util.slicedmap.*;
025    
026    import java.util.Collection;
027    import java.util.List;
028    
029    public class BindingTraceContext implements BindingTrace {
030        private final List<Diagnostic> diagnosticList = Lists.newArrayList();
031        private final Diagnostics diagnostics;
032    
033        // These flags are used for debugging of "Rewrite at slice..." exceptions
034        /* package */ final static boolean TRACK_REWRITES = false;
035        /* package */ final static boolean TRACK_WITH_STACK_TRACES = true;
036    
037        private final MutableSlicedMap map;
038    
039        private final BindingContext bindingContext = new BindingContext() {
040    
041            @NotNull
042            @Override
043            public Diagnostics getDiagnostics() {
044                return diagnostics;
045            }
046    
047            @Override
048            public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
049                return BindingTraceContext.this.get(slice, key);
050            }
051    
052            @NotNull
053            @Override
054            public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
055                return BindingTraceContext.this.getKeys(slice);
056            }
057    
058            @NotNull
059            @TestOnly
060            @Override
061            public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull ReadOnlySlice<K, V> slice) {
062                return map.getSliceContents(slice);
063            }
064        };
065    
066        public BindingTraceContext() {
067            //noinspection ConstantConditions
068            this(TRACK_REWRITES ? new TrackingSlicedMap(TRACK_WITH_STACK_TRACES) : SlicedMapImpl.create());
069        }
070    
071    
072        private BindingTraceContext(@NotNull MutableSlicedMap map) {
073            this.map = map;
074            this.diagnostics = new DiagnosticsWithSuppression(getBindingContext(), diagnosticList);
075        }
076    
077        @TestOnly
078        public static BindingTraceContext createTraceableBindingTrace() {
079            return new BindingTraceContext(new TrackingSlicedMap(TRACK_WITH_STACK_TRACES));
080        }
081    
082        @Override
083        public void report(@NotNull Diagnostic diagnostic) {
084            diagnosticList.add(diagnostic);
085        }
086    
087        public void clearDiagnostics() {
088            diagnosticList.clear();
089        }
090    
091        @NotNull
092        @Override
093        public BindingContext getBindingContext() {
094            return bindingContext;
095        }
096    
097        @Override
098        public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
099            map.put(slice, key, value);
100        }
101    
102        @Override
103        public <K> void record(WritableSlice<K, Boolean> slice, K key) {
104            record(slice, key, true);
105        }
106    
107        @Override
108        public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
109            return map.get(slice, key);
110        }
111    
112        @NotNull
113        @Override
114        public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) {
115            return map.getKeys(slice);
116        }
117    }