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.google.common.collect.ImmutableMap; 020 import org.jetbrains.annotations.NotNull; 021 import org.jetbrains.annotations.Nullable; 022 import org.jetbrains.annotations.TestOnly; 023 import org.jetbrains.kotlin.diagnostics.Diagnostic; 024 import org.jetbrains.kotlin.psi.KtExpression; 025 import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics; 026 import org.jetbrains.kotlin.resolve.diagnostics.MutableDiagnosticsWithSuppression; 027 import org.jetbrains.kotlin.types.KotlinType; 028 import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo; 029 import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt; 030 import org.jetbrains.kotlin.util.slicedMap.*; 031 032 import java.util.Collection; 033 034 public class BindingTraceContext implements BindingTrace { 035 // These flags are used for debugging of "Rewrite at slice..." exceptions 036 /* package */ final static boolean TRACK_REWRITES = false; 037 /* package */ final static boolean TRACK_WITH_STACK_TRACES = true; 038 039 private final MutableSlicedMap map; 040 private final MutableDiagnosticsWithSuppression mutableDiagnostics; 041 042 private final BindingContext bindingContext = new BindingContext() { 043 044 @NotNull 045 @Override 046 public Diagnostics getDiagnostics() { 047 return mutableDiagnostics; 048 } 049 050 @Override 051 public <K, V> V get(ReadOnlySlice<K, V> slice, K key) { 052 return BindingTraceContext.this.get(slice, key); 053 } 054 055 @NotNull 056 @Override 057 public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) { 058 return BindingTraceContext.this.getKeys(slice); 059 } 060 061 @NotNull 062 @TestOnly 063 @Override 064 public <K, V> ImmutableMap<K, V> getSliceContents(@NotNull ReadOnlySlice<K, V> slice) { 065 return map.getSliceContents(slice); 066 } 067 068 @Nullable 069 @Override 070 public KotlinType getType(@NotNull KtExpression expression) { 071 return BindingTraceContext.this.getType(expression); 072 } 073 074 @Override 075 public void addOwnDataTo(@NotNull BindingTrace trace, boolean commitDiagnostics) { 076 BindingContextUtils.addOwnDataTo(trace, null, commitDiagnostics, map, mutableDiagnostics); 077 } 078 }; 079 080 public BindingTraceContext() { 081 //noinspection ConstantConditions 082 this(TRACK_REWRITES ? new TrackingSlicedMap(TRACK_WITH_STACK_TRACES) : SlicedMapImpl.create()); 083 } 084 085 086 private BindingTraceContext(@NotNull MutableSlicedMap map) { 087 this.map = map; 088 this.mutableDiagnostics = new MutableDiagnosticsWithSuppression(bindingContext, Diagnostics.Companion.getEMPTY()); 089 } 090 091 @TestOnly 092 public static BindingTraceContext createTraceableBindingTrace() { 093 return new BindingTraceContext(new TrackingSlicedMap(TRACK_WITH_STACK_TRACES)); 094 } 095 096 @Override 097 public void report(@NotNull Diagnostic diagnostic) { 098 mutableDiagnostics.report(diagnostic); 099 } 100 101 public void clearDiagnostics() { 102 mutableDiagnostics.clear(); 103 } 104 105 @NotNull 106 @Override 107 public BindingContext getBindingContext() { 108 return bindingContext; 109 } 110 111 @Override 112 public <K, V> void record(WritableSlice<K, V> slice, K key, V value) { 113 map.put(slice, key, value); 114 } 115 116 @Override 117 public <K> void record(WritableSlice<K, Boolean> slice, K key) { 118 record(slice, key, true); 119 } 120 121 @Override 122 public <K, V> V get(ReadOnlySlice<K, V> slice, K key) { 123 return map.get(slice, key); 124 } 125 126 @NotNull 127 @Override 128 public <K, V> Collection<K> getKeys(WritableSlice<K, V> slice) { 129 return map.getKeys(slice); 130 } 131 132 @Nullable 133 @Override 134 public KotlinType getType(@NotNull KtExpression expression) { 135 KotlinTypeInfo typeInfo = get(BindingContext.EXPRESSION_TYPE_INFO, expression); 136 return typeInfo != null ? typeInfo.getType() : null; 137 } 138 139 @Override 140 public void recordType(@NotNull KtExpression expression, @Nullable KotlinType type) { 141 KotlinTypeInfo typeInfo = get(BindingContext.EXPRESSION_TYPE_INFO, expression); 142 typeInfo = typeInfo != null ? typeInfo.replaceType(type) : TypeInfoFactoryKt.createTypeInfo(type); 143 record(BindingContext.EXPRESSION_TYPE_INFO, expression, typeInfo); 144 } 145 }