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 017package org.jetbrains.jet.lang.resolve.calls.tasks; 018 019import com.google.common.collect.Lists; 020import com.google.common.collect.Sets; 021import org.jetbrains.annotations.NotNull; 022import org.jetbrains.jet.lang.descriptors.*; 023import org.jetbrains.jet.lang.resolve.DescriptorUtils; 024import org.jetbrains.jet.lang.resolve.name.Name; 025import org.jetbrains.jet.lang.resolve.scopes.JetScope; 026import org.jetbrains.jet.lang.types.ErrorUtils; 027import org.jetbrains.jet.lang.types.JetType; 028 029import java.util.*; 030 031public 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}