001 /*
002 * Copyright 2010-2015 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.kotlin.descriptors.impl;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.kotlin.descriptors.*;
022 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
023 import org.jetbrains.kotlin.name.Name;
024 import org.jetbrains.kotlin.resolve.DescriptorFactory;
025 import org.jetbrains.kotlin.types.DescriptorSubstitutor;
026 import org.jetbrains.kotlin.types.KotlinType;
027 import org.jetbrains.kotlin.types.TypeSubstitutor;
028 import org.jetbrains.kotlin.types.Variance;
029 import org.jetbrains.kotlin.utils.CollectionsKt;
030 import org.jetbrains.kotlin.utils.SmartSet;
031
032 import java.util.ArrayList;
033 import java.util.Collection;
034 import java.util.List;
035 import java.util.Set;
036
037 public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRootImpl implements FunctionDescriptor {
038 private List<TypeParameterDescriptor> typeParameters;
039 private List<ValueParameterDescriptor> unsubstitutedValueParameters;
040 private KotlinType unsubstitutedReturnType;
041 private ReceiverParameterDescriptor extensionReceiverParameter;
042 private ReceiverParameterDescriptor dispatchReceiverParameter;
043 private Modality modality;
044 private Visibility visibility = Visibilities.UNKNOWN;
045 private boolean isOperator = false;
046 private boolean isInfix = false;
047 private boolean isExternal = false;
048 private boolean isInline = false;
049 private boolean isTailrec = false;
050 private final Set<FunctionDescriptor> overriddenFunctions = SmartSet.create();
051 private final FunctionDescriptor original;
052 private final Kind kind;
053
054 protected FunctionDescriptorImpl(
055 @NotNull DeclarationDescriptor containingDeclaration,
056 @Nullable FunctionDescriptor original,
057 @NotNull Annotations annotations,
058 @NotNull Name name,
059 @NotNull Kind kind,
060 @NotNull SourceElement source
061 ) {
062 super(containingDeclaration, annotations, name, source);
063 this.original = original == null ? this : original;
064 this.kind = kind;
065 }
066
067 @NotNull
068 public FunctionDescriptorImpl initialize(
069 @Nullable KotlinType receiverParameterType,
070 @Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
071 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
072 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
073 @Nullable KotlinType unsubstitutedReturnType,
074 @Nullable Modality modality,
075 @NotNull Visibility visibility
076 ) {
077 this.typeParameters = CollectionsKt.toReadOnlyList(typeParameters);
078 this.unsubstitutedValueParameters = unsubstitutedValueParameters;
079 this.unsubstitutedReturnType = unsubstitutedReturnType;
080 this.modality = modality;
081 this.visibility = visibility;
082 this.extensionReceiverParameter = DescriptorFactory.createExtensionReceiverParameterForCallable(this, receiverParameterType);
083 this.dispatchReceiverParameter = dispatchReceiverParameter;
084
085 for (int i = 0; i < typeParameters.size(); ++i) {
086 TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
087 if (typeParameterDescriptor.getIndex() != i) {
088 throw new IllegalStateException(typeParameterDescriptor + " index is " + typeParameterDescriptor.getIndex() + " but position is " + i);
089 }
090 }
091
092 for (int i = 0; i < unsubstitutedValueParameters.size(); ++i) {
093 // TODO fill me
094 int firstValueParameterOffset = 0; // receiverParameter.exists() ? 1 : 0;
095 ValueParameterDescriptor valueParameterDescriptor = unsubstitutedValueParameters.get(i);
096 if (valueParameterDescriptor.getIndex() != i + firstValueParameterOffset) {
097 throw new IllegalStateException(valueParameterDescriptor + "index is " + valueParameterDescriptor.getIndex() + " but position is " + i);
098 }
099 }
100
101 return this;
102 }
103
104 public void setVisibility(@NotNull Visibility visibility) {
105 this.visibility = visibility;
106 }
107
108 public void setOperator(boolean isOperator) {
109 this.isOperator = isOperator;
110 }
111
112 public void setInfix(boolean isInfix) {
113 this.isInfix = isInfix;
114 }
115
116 public void setExternal(boolean isExternal) {
117 this.isExternal = isExternal;
118 }
119
120 public void setInline(boolean isInline) {
121 this.isInline = isInline;
122 }
123
124 public void setTailrec(boolean isTailrec) {
125 this.isTailrec = isTailrec;
126 }
127
128 public void setReturnType(@NotNull KotlinType unsubstitutedReturnType) {
129 if (this.unsubstitutedReturnType != null) {
130 // TODO: uncomment and fix tests
131 //throw new IllegalStateException("returnType already set");
132 }
133 this.unsubstitutedReturnType = unsubstitutedReturnType;
134 }
135
136 @Nullable
137 @Override
138 public ReceiverParameterDescriptor getExtensionReceiverParameter() {
139 return extensionReceiverParameter;
140 }
141
142 @Nullable
143 @Override
144 public ReceiverParameterDescriptor getDispatchReceiverParameter() {
145 return dispatchReceiverParameter;
146 }
147
148 @NotNull
149 @Override
150 public Collection<? extends FunctionDescriptor> getOverriddenDescriptors() {
151 return overriddenFunctions;
152 }
153
154 @NotNull
155 @Override
156 public Modality getModality() {
157 return modality;
158 }
159
160 @NotNull
161 @Override
162 public Visibility getVisibility() {
163 return visibility;
164 }
165
166 @Override
167 public boolean isOperator() {
168 if (isOperator) return true;
169
170 for (FunctionDescriptor descriptor : overriddenFunctions) {
171 if (descriptor.isOperator()) return true;
172 }
173
174 return false;
175 }
176
177 @Override
178 public boolean isInfix() {
179 if (isInfix) return true;
180
181 for (FunctionDescriptor descriptor : overriddenFunctions) {
182 if (descriptor.isInfix()) return true;
183 }
184
185 return false;
186 }
187
188 @Override
189 public boolean isExternal() {
190 return isExternal;
191 }
192
193 @Override
194 public boolean isInline() {
195 return isInline;
196 }
197
198 @Override
199 public boolean isTailrec() {
200 return isTailrec;
201 }
202
203 @Override
204 public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
205 overriddenFunctions.add((FunctionDescriptor) overriddenFunction);
206 }
207
208 @Override
209 @NotNull
210 public List<TypeParameterDescriptor> getTypeParameters() {
211 return typeParameters;
212 }
213
214 @Override
215 @NotNull
216 public List<ValueParameterDescriptor> getValueParameters() {
217 return unsubstitutedValueParameters;
218 }
219
220 @Override
221 public boolean hasStableParameterNames() {
222 return true;
223 }
224
225 @Override
226 public boolean hasSynthesizedParameterNames() {
227 return false;
228 }
229
230 @Override
231 public KotlinType getReturnType() {
232 return unsubstitutedReturnType;
233 }
234
235 @NotNull
236 @Override
237 public FunctionDescriptor getOriginal() {
238 return original == this ? this : original.getOriginal();
239 }
240
241 @NotNull
242 @Override
243 public Kind getKind() {
244 return kind;
245 }
246
247 @Override
248 public final FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
249 if (originalSubstitutor.isEmpty()) {
250 return this;
251 }
252 return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility,
253 isOperator, isInfix, isExternal, isInline, isTailrec,
254 getOriginal(), true, getKind());
255 }
256
257 @Nullable
258 protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor,
259 @NotNull DeclarationDescriptor newOwner,
260 @NotNull Modality newModality,
261 @NotNull Visibility newVisibility,
262 boolean isOperator,
263 boolean isInfix,
264 boolean isExternal,
265 boolean isInline,
266 boolean isTailrec,
267 @Nullable FunctionDescriptor original,
268 boolean copyOverrides,
269 @NotNull Kind kind
270 ) {
271 return doSubstitute(originalSubstitutor,
272 newOwner, newModality, newVisibility, isOperator, isInfix, isExternal, isInline, isTailrec, original, copyOverrides, kind,
273 getValueParameters(), getExtensionReceiverParameterType(), getReturnType()
274 );
275 }
276
277 @Nullable
278 protected KotlinType getExtensionReceiverParameterType() {
279 if (extensionReceiverParameter == null) return null;
280 return extensionReceiverParameter.getType();
281 }
282
283
284 @Nullable
285 protected FunctionDescriptor doSubstitute(@NotNull TypeSubstitutor originalSubstitutor,
286 @NotNull DeclarationDescriptor newOwner,
287 @NotNull Modality newModality,
288 @NotNull Visibility newVisibility,
289 boolean isOperator,
290 boolean isInfix,
291 boolean isExternal,
292 boolean isInline,
293 boolean isTailrec,
294 @Nullable FunctionDescriptor original,
295 boolean copyOverrides,
296 @NotNull Kind kind,
297 @NotNull List<ValueParameterDescriptor> newValueParameterDescriptors,
298 @Nullable KotlinType newExtensionReceiverParameterType,
299 @NotNull KotlinType newReturnType
300 ) {
301 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, original, kind);
302
303 List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
304 List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
305 TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
306 originalTypeParameters, originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
307 );
308
309 KotlinType substitutedReceiverParameterType = null;
310 if (newExtensionReceiverParameterType != null) {
311 substitutedReceiverParameterType = substitutor.substitute(newExtensionReceiverParameterType, Variance.IN_VARIANCE);
312 if (substitutedReceiverParameterType == null) {
313 return null;
314 }
315 }
316
317 ReceiverParameterDescriptor substitutedExpectedThis = null;
318 if (dispatchReceiverParameter != null) {
319 // When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
320 // E.g.
321 // class Base { fun foo() }
322 // class Derived : Base
323 // val x: Base
324 // if (x is Derived) {
325 // // `x` shouldn't be marked as smart-cast
326 // // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
327 // x.foo()
328 // }
329 substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
330 if (substitutedExpectedThis == null) {
331 return null;
332 }
333 }
334
335 List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
336 substitutedDescriptor, newValueParameterDescriptors, substitutor
337 );
338 if (substitutedValueParameters == null) {
339 return null;
340 }
341
342 KotlinType substitutedReturnType = substitutor.substitute(newReturnType, Variance.OUT_VARIANCE);
343 if (substitutedReturnType == null) {
344 return null;
345 }
346
347 substitutedDescriptor.initialize(
348 substitutedReceiverParameterType,
349 substitutedExpectedThis,
350 substitutedTypeParameters,
351 substitutedValueParameters,
352 substitutedReturnType,
353 newModality,
354 newVisibility
355 );
356 substitutedDescriptor.setOperator(isOperator);
357 substitutedDescriptor.setInfix(isInfix);
358 substitutedDescriptor.setExternal(isExternal);
359 substitutedDescriptor.setInline(isInline);
360 substitutedDescriptor.setTailrec(isTailrec);
361
362 if (copyOverrides) {
363 for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
364 substitutedDescriptor.addOverriddenDescriptor(overriddenFunction.substitute(substitutor));
365 }
366 }
367
368 return substitutedDescriptor;
369 }
370
371 @NotNull
372 protected abstract FunctionDescriptorImpl createSubstitutedCopy(
373 @NotNull DeclarationDescriptor newOwner,
374 @Nullable FunctionDescriptor original,
375 @NotNull Kind kind
376 );
377
378 @Override
379 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
380 return visitor.visitFunctionDescriptor(this, data);
381 }
382
383 @Nullable
384 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(
385 FunctionDescriptor substitutedDescriptor,
386 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
387 @NotNull TypeSubstitutor substitutor
388 ) {
389 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(unsubstitutedValueParameters.size());
390 for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
391 // TODO : Lazy?
392 KotlinType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
393 KotlinType varargElementType = unsubstitutedValueParameter.getVarargElementType();
394 KotlinType substituteVarargElementType =
395 varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
396 if (substitutedType == null) return null;
397 result.add(
398 new ValueParameterDescriptorImpl(
399 substitutedDescriptor,
400 unsubstitutedValueParameter,
401 unsubstitutedValueParameter.getIndex(),
402 unsubstitutedValueParameter.getAnnotations(),
403 unsubstitutedValueParameter.getName(),
404 substitutedType,
405 unsubstitutedValueParameter.declaresDefaultValue(),
406 unsubstitutedValueParameter.isCrossinline(),
407 unsubstitutedValueParameter.isNoinline(),
408 substituteVarargElementType,
409 SourceElement.NO_SOURCE
410 )
411 );
412 }
413 return result;
414 }
415 }