diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index df52ff2bb47..474f094fb15 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement; import jet.runtime.typeinfo.KotlinSignature; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.ReadOnly; import org.jetbrains.annotations.TestOnly; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -261,6 +262,7 @@ public interface BindingContext { // slice.isCollective() must be true @NotNull + @ReadOnly Collection getKeys(WritableSlice slice); /** This method should be used only for debug and testing */ diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/CompositeBindingContext.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/CompositeBindingContext.kt new file mode 100644 index 00000000000..47dbecadb23 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/CompositeBindingContext.kt @@ -0,0 +1,81 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve + +import org.jetbrains.jet.util.slicedmap.ReadOnlySlice +import org.jetbrains.jet.util.slicedmap.WritableSlice +import com.google.common.collect.ImmutableMap +import org.jetbrains.jet.lang.diagnostics.Diagnostic +import com.intellij.psi.PsiElement + +class CompositeBindingContext private ( + private val delegates: List +) : BindingContext { + + class object { + public fun create(delegates: List): BindingContext { + if (delegates.isEmpty()) return BindingContext.EMPTY + if (delegates.size == 1) return delegates.first() + return CompositeBindingContext(delegates) + } + } + + override fun get(slice: ReadOnlySlice?, key: K?): V? { + return delegates.stream().map { it[slice, key] }.firstOrNull { it != null } + } + + override fun getKeys(slice: WritableSlice?): Collection { + return delegates.flatMap { it.getKeys(slice) } + } + + override fun getSliceContents(slice: ReadOnlySlice): ImmutableMap { + val builder = ImmutableMap.builder()!! + for (delegate in delegates) { + builder.putAll(delegate.getSliceContents(slice)) + } + return builder.build()!! + } + + override fun getDiagnostics(): Diagnostics { + return CompositeDiagnostics(delegates.map { it.getDiagnostics() }) + } + + private class CompositeDiagnostics( + private val delegates: List + ) : Diagnostics { + override fun iterator(): Iterator { + val emptyStream = listOf().stream() + return delegates.fold(emptyStream, { r, t -> r + t.stream()}).iterator() + } + + override fun all(): Collection { + return delegates.flatMap { it.all() } + } + + override fun forElement(psiElement: PsiElement): Collection { + return delegates.flatMap { it.forElement(psiElement) } + } + + override fun isEmpty(): Boolean { + return delegates.all { it.isEmpty() } + } + + override fun noSuppression(): Diagnostics { + return CompositeDiagnostics(delegates.map { it.noSuppression() }) + } + } +}