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.descriptors.impl;
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.Nullable;
023 import org.jetbrains.jet.lang.descriptors.*;
024 import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
025 import org.jetbrains.jet.lang.resolve.DescriptorFactory;
026 import org.jetbrains.jet.lang.resolve.OverridingUtil;
027 import org.jetbrains.jet.lang.resolve.name.Name;
028 import org.jetbrains.jet.lang.types.DescriptorSubstitutor;
029 import org.jetbrains.jet.lang.types.JetType;
030 import org.jetbrains.jet.lang.types.TypeSubstitutor;
031 import org.jetbrains.jet.lang.types.Variance;
032
033 import java.util.ArrayList;
034 import java.util.List;
035 import java.util.Set;
036
037 public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRootImpl implements FunctionDescriptor {
038
039 protected List<TypeParameterDescriptor> typeParameters;
040 protected List<ValueParameterDescriptor> unsubstitutedValueParameters;
041 protected JetType unsubstitutedReturnType;
042 private ReceiverParameterDescriptor receiverParameter;
043 protected ReceiverParameterDescriptor expectedThisObject;
044 protected Modality modality;
045
046 protected Visibility visibility;
047 protected final Set<FunctionDescriptor> overriddenFunctions = Sets.newLinkedHashSet(); // LinkedHashSet is essential here
048 private final FunctionDescriptor original;
049 private final Kind kind;
050
051 protected FunctionDescriptorImpl(
052 @NotNull DeclarationDescriptor containingDeclaration,
053 @Nullable FunctionDescriptor original,
054 @NotNull Annotations annotations,
055 @NotNull Name name,
056 @NotNull Kind kind,
057 @NotNull SourceElement source
058 ) {
059 super(containingDeclaration, annotations, name, source);
060 this.original = original == null ? this : original;
061 this.kind = kind;
062 }
063
064 @NotNull
065 public FunctionDescriptorImpl initialize(
066 @Nullable JetType receiverParameterType,
067 @Nullable ReceiverParameterDescriptor expectedThisObject,
068 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
069 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
070 @Nullable JetType unsubstitutedReturnType,
071 @Nullable Modality modality,
072 @NotNull Visibility visibility) {
073 this.typeParameters = Lists.newArrayList(typeParameters);
074 this.unsubstitutedValueParameters = unsubstitutedValueParameters;
075 this.unsubstitutedReturnType = unsubstitutedReturnType;
076 this.modality = modality;
077 this.visibility = visibility;
078 this.receiverParameter = DescriptorFactory.createReceiverParameterForCallable(this, receiverParameterType);
079 this.expectedThisObject = expectedThisObject;
080
081 for (int i = 0; i < typeParameters.size(); ++i) {
082 TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
083 if (typeParameterDescriptor.getIndex() != i) {
084 throw new IllegalStateException(typeParameterDescriptor + " index is " + typeParameterDescriptor.getIndex() + " but position is " + i);
085 }
086 }
087
088 for (int i = 0; i < unsubstitutedValueParameters.size(); ++i) {
089 // TODO fill me
090 int firstValueParameterOffset = 0; // receiverParameter.exists() ? 1 : 0;
091 ValueParameterDescriptor valueParameterDescriptor = unsubstitutedValueParameters.get(i);
092 if (valueParameterDescriptor.getIndex() != i + firstValueParameterOffset) {
093 throw new IllegalStateException(valueParameterDescriptor + "index is " + valueParameterDescriptor.getIndex() + " but position is " + i);
094 }
095 }
096
097 return this;
098 }
099
100 public void setVisibility(@NotNull Visibility visibility) {
101 this.visibility = visibility;
102 }
103
104 public void setReturnType(@NotNull JetType unsubstitutedReturnType) {
105 if (this.unsubstitutedReturnType != null) {
106 // TODO: uncomment and fix tests
107 //throw new IllegalStateException("returnType already set");
108 }
109 this.unsubstitutedReturnType = unsubstitutedReturnType;
110 }
111
112 @Nullable
113 @Override
114 public ReceiverParameterDescriptor getReceiverParameter() {
115 return receiverParameter;
116 }
117
118 @Nullable
119 @Override
120 public ReceiverParameterDescriptor getExpectedThisObject() {
121 return expectedThisObject;
122 }
123
124 @NotNull
125 @Override
126 public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
127 return overriddenFunctions;
128 }
129
130 @NotNull
131 @Override
132 public Modality getModality() {
133 return modality;
134 }
135
136 @NotNull
137 @Override
138 public Visibility getVisibility() {
139 return visibility;
140 }
141
142 @Override
143 public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
144 overriddenFunctions.add((FunctionDescriptor) overriddenFunction);
145 }
146
147 @Override
148 @NotNull
149 public List<TypeParameterDescriptor> getTypeParameters() {
150 return typeParameters;
151 }
152
153 @Override
154 @NotNull
155 public List<ValueParameterDescriptor> getValueParameters() {
156 return unsubstitutedValueParameters;
157 }
158
159 @Override
160 public boolean hasStableParameterNames() {
161 return true;
162 }
163
164 @Override
165 public boolean hasSynthesizedParameterNames() {
166 return false;
167 }
168
169 @Override
170 public JetType getReturnType() {
171 return unsubstitutedReturnType;
172 }
173
174 @NotNull
175 @Override
176 public FunctionDescriptor getOriginal() {
177 return original == this ? this : original.getOriginal();
178 }
179
180 @NotNull
181 @Override
182 public Kind getKind() {
183 return kind;
184 }
185
186 @Override
187 public final FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
188 if (originalSubstitutor.isEmpty()) {
189 return this;
190 }
191 return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility, getOriginal(), true, getKind());
192 }
193
194 @Nullable
195 protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor,
196 @NotNull DeclarationDescriptor newOwner,
197 @NotNull Modality newModality,
198 @NotNull Visibility newVisibility,
199 @Nullable FunctionDescriptor original,
200 boolean copyOverrides,
201 @NotNull Kind kind
202 ) {
203 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, original, kind);
204
205 List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
206 TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
207
208 JetType substitutedReceiverParameterType = null;
209 if (receiverParameter != null) {
210 substitutedReceiverParameterType = substitutor.substitute(getReceiverParameter().getType(), Variance.IN_VARIANCE);
211 if (substitutedReceiverParameterType == null) {
212 return null;
213 }
214 }
215
216 ReceiverParameterDescriptor substitutedExpectedThis = null;
217 if (expectedThisObject != null) {
218 substitutedExpectedThis = expectedThisObject.substitute(substitutor);
219 if (substitutedExpectedThis == null) {
220 return null;
221 }
222 }
223
224 List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(substitutedDescriptor, this, substitutor);
225 if (substitutedValueParameters == null) {
226 return null;
227 }
228
229 JetType substitutedReturnType = substitutor.substitute(getReturnType(), Variance.OUT_VARIANCE);
230 if (substitutedReturnType == null) {
231 return null;
232 }
233
234 substitutedDescriptor.initialize(
235 substitutedReceiverParameterType,
236 substitutedExpectedThis,
237 substitutedTypeParameters,
238 substitutedValueParameters,
239 substitutedReturnType,
240 newModality,
241 newVisibility
242 );
243 if (copyOverrides) {
244 for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
245 OverridingUtil.bindOverride(substitutedDescriptor, overriddenFunction.substitute(substitutor));
246 }
247 }
248 return substitutedDescriptor;
249 }
250
251 @NotNull
252 protected abstract FunctionDescriptorImpl createSubstitutedCopy(
253 @NotNull DeclarationDescriptor newOwner,
254 @Nullable FunctionDescriptor original,
255 @NotNull Kind kind
256 );
257
258 @Override
259 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
260 return visitor.visitFunctionDescriptor(this, data);
261 }
262
263 @Nullable
264 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeSubstitutor substitutor) {
265 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
266 List<ValueParameterDescriptor> unsubstitutedValueParameters = functionDescriptor.getValueParameters();
267 for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
268 // TODO : Lazy?
269 JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
270 JetType varargElementType = unsubstitutedValueParameter.getVarargElementType();
271 JetType substituteVarargElementType = varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
272 if (substitutedType == null) return null;
273 result.add(new ValueParameterDescriptorImpl(
274 substitutedDescriptor,
275 unsubstitutedValueParameter,
276 unsubstitutedValueParameter.getIndex(),
277 unsubstitutedValueParameter.getAnnotations(),
278 unsubstitutedValueParameter.getName(),
279 substitutedType,
280 unsubstitutedValueParameter.declaresDefaultValue(),
281 substituteVarargElementType,
282 SourceElement.NO_SOURCE
283 )
284 );
285 }
286 return result;
287 }
288 }