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