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.calls.tasks;
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.jet.lang.descriptors.*;
023 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
024 import org.jetbrains.jet.lang.resolve.name.Name;
025 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
026 import org.jetbrains.jet.lang.types.ErrorUtils;
027 import org.jetbrains.jet.lang.types.JetType;
028
029 import java.util.*;
030
031 public class CallableDescriptorCollectors {
032 public static CallableDescriptorCollector<FunctionDescriptor> FUNCTIONS = new FunctionCollector();
033 public static CallableDescriptorCollector<VariableDescriptor> VARIABLES = new VariableCollector();
034 public static CallableDescriptorCollector<VariableDescriptor> PROPERTIES = new PropertyCollector();
035 public static List<CallableDescriptorCollector<? extends CallableDescriptor>> FUNCTIONS_AND_VARIABLES =
036 Lists.newArrayList(FUNCTIONS, VARIABLES);
037
038 private static class FunctionCollector implements CallableDescriptorCollector<FunctionDescriptor> {
039
040 @NotNull
041 @Override
042 public Collection<FunctionDescriptor> getNonExtensionsByName(JetScope scope, Name name) {
043 Set<FunctionDescriptor> functions = Sets.newLinkedHashSet(scope.getFunctions(name));
044 for (Iterator<FunctionDescriptor> iterator = functions.iterator(); iterator.hasNext(); ) {
045 FunctionDescriptor functionDescriptor = iterator.next();
046 if (functionDescriptor.getReceiverParameter() != null) {
047 iterator.remove();
048 }
049 }
050 addConstructors(scope, name, functions);
051 return functions;
052 }
053
054 @NotNull
055 @Override
056 public Collection<FunctionDescriptor> getMembersByName(@NotNull JetType receiverType, Name name) {
057 JetScope receiverScope = receiverType.getMemberScope();
058 Set<FunctionDescriptor> members = Sets.newHashSet(receiverScope.getFunctions(name));
059 addConstructors(receiverScope, name, members);
060 return members;
061 }
062
063 @NotNull
064 @Override
065 public Collection<FunctionDescriptor> getNonMembersByName(JetScope scope, Name name) {
066 return scope.getFunctions(name);
067 }
068
069 private static void addConstructors(JetScope scope, Name name, Collection<FunctionDescriptor> functions) {
070 ClassifierDescriptor classifier = scope.getClassifier(name);
071 if (classifier instanceof ClassDescriptor && !ErrorUtils.isError(classifier.getTypeConstructor())) {
072 ClassDescriptor classDescriptor = (ClassDescriptor) classifier;
073 functions.addAll(classDescriptor.getConstructors());
074 }
075 }
076
077 @Override
078 public String toString() {
079 return "FUNCTIONS";
080 }
081 }
082
083 private static class VariableCollector implements CallableDescriptorCollector<VariableDescriptor> {
084
085 @NotNull
086 @Override
087 public Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, Name name) {
088 VariableDescriptor descriptor = scope.getLocalVariable(name);
089 if (descriptor == null) {
090 descriptor = DescriptorUtils.filterNonExtensionProperty(scope.getProperties(name));
091 }
092 if (descriptor == null) return Collections.emptyList();
093 return Collections.singleton(descriptor);
094 }
095
096 @NotNull
097 @Override
098 public Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiverType, Name name) {
099 return receiverType.getMemberScope().getProperties(name);
100 }
101
102 @NotNull
103 @Override
104 public Collection<VariableDescriptor> getNonMembersByName(JetScope scope, Name name) {
105 Collection<VariableDescriptor> result = Sets.newLinkedHashSet();
106
107 VariableDescriptor localVariable = scope.getLocalVariable(name);
108 if (localVariable != null) {
109 result.add(localVariable);
110 }
111 result.addAll(scope.getProperties(name));
112 return result;
113 }
114
115 @Override
116 public String toString() {
117 return "VARIABLES";
118 }
119 }
120
121 private static class PropertyCollector implements CallableDescriptorCollector<VariableDescriptor> {
122 private static Collection<VariableDescriptor> filterProperties(Collection<? extends VariableDescriptor> variableDescriptors) {
123 ArrayList<VariableDescriptor> properties = Lists.newArrayList();
124 for (VariableDescriptor descriptor : variableDescriptors) {
125 if (descriptor instanceof PropertyDescriptor) {
126 properties.add(descriptor);
127 }
128 }
129 return properties;
130 }
131
132 @NotNull
133 @Override
134 public Collection<VariableDescriptor> getNonExtensionsByName(JetScope scope, Name name) {
135 return filterProperties(VARIABLES.getNonExtensionsByName(scope, name));
136 }
137
138 @NotNull
139 @Override
140 public Collection<VariableDescriptor> getMembersByName(@NotNull JetType receiver, Name name) {
141 return filterProperties(VARIABLES.getMembersByName(receiver, name));
142 }
143
144 @NotNull
145 @Override
146 public Collection<VariableDescriptor> getNonMembersByName(JetScope scope, Name name) {
147 return filterProperties(VARIABLES.getNonMembersByName(scope, name));
148 }
149
150 @Override
151 public String toString() {
152 return "PROPERTIES";
153 }
154 }
155
156 private CallableDescriptorCollectors() {
157 }
158 }