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.scopes;
018
019 import com.google.common.collect.Lists;
020 import com.google.common.collect.Sets;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.TestOnly;
023 import org.jetbrains.jet.lang.descriptors.*;
024 import org.jetbrains.jet.lang.resolve.name.LabelName;
025 import org.jetbrains.jet.lang.resolve.name.Name;
026 import org.jetbrains.jet.utils.Printer;
027
028 import java.util.*;
029
030 import static org.jetbrains.jet.lang.resolve.scopes.JetScopeSelectorUtil.*;
031
032 public class ChainedScope implements JetScope {
033 private final DeclarationDescriptor containingDeclaration;
034 private final String debugName;
035 private final JetScope[] scopeChain;
036 private Collection<DeclarationDescriptor> allDescriptors;
037 private List<ReceiverParameterDescriptor> implicitReceiverHierarchy;
038
039 public ChainedScope(DeclarationDescriptor containingDeclaration, String debugName, JetScope... scopes) {
040 this.containingDeclaration = containingDeclaration;
041 scopeChain = scopes.clone();
042
043 this.debugName = debugName;
044 }
045
046 @Override
047 public ClassifierDescriptor getClassifier(@NotNull Name name) {
048 return getFirstMatch(scopeChain, name, CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR);
049 }
050
051 @Override
052 public PackageViewDescriptor getPackage(@NotNull Name name) {
053 return getFirstMatch(scopeChain, name, PACKAGE_SCOPE_SELECTOR);
054 }
055
056 @NotNull
057 @Override
058 public Set<VariableDescriptor> getProperties(@NotNull Name name) {
059 return getFromAllScopes(scopeChain, name, NAMED_PROPERTIES_SCOPE_SELECTOR);
060 }
061
062 @Override
063 public VariableDescriptor getLocalVariable(@NotNull Name name) {
064 return getFirstMatch(scopeChain, name, VARIABLE_DESCRIPTOR_SCOPE_SELECTOR);
065 }
066
067 @NotNull
068 @Override
069 public Set<FunctionDescriptor> getFunctions(@NotNull Name name) {
070 return getFromAllScopes(scopeChain, name, NAMED_FUNCTION_SCOPE_SELECTOR);
071 }
072
073 @NotNull
074 @Override
075 public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
076 if (implicitReceiverHierarchy == null) {
077 implicitReceiverHierarchy = Lists.newArrayList();
078 for (JetScope jetScope : scopeChain) {
079 implicitReceiverHierarchy.addAll(jetScope.getImplicitReceiversHierarchy());
080 }
081 }
082 return implicitReceiverHierarchy;
083 }
084
085 @NotNull
086 @Override
087 public DeclarationDescriptor getContainingDeclaration() {
088 return containingDeclaration;
089 }
090
091 @NotNull
092 @Override
093 public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
094 ArrayList<DeclarationDescriptor> result = new ArrayList<DeclarationDescriptor>();
095 for (JetScope jetScope : scopeChain) {
096 result.addAll(jetScope.getDeclarationsByLabel(labelName));
097 }
098 result.trimToSize();
099 return result;
100 }
101
102 @NotNull
103 @Override
104 public Collection<DeclarationDescriptor> getAllDescriptors() {
105 if (allDescriptors == null) {
106 allDescriptors = Sets.newHashSet();
107 for (JetScope scope : scopeChain) {
108 allDescriptors.addAll(scope.getAllDescriptors());
109 }
110 }
111 return allDescriptors;
112 }
113
114 @NotNull
115 @Override
116 public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
117 throw new UnsupportedOperationException();
118 }
119
120 @Override
121 public String toString() {
122 return debugName;
123 }
124
125 @TestOnly
126 @Override
127 public void printScopeStructure(@NotNull Printer p) {
128 p.println(getClass().getSimpleName(), ": ", debugName, " {");
129 p.pushIndent();
130
131 for (JetScope scope : scopeChain) {
132 scope.printScopeStructure(p);
133 }
134
135 p.popIndent();
136 p.println("}");
137 }
138 }