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.AnnotationDescriptor;
025 import org.jetbrains.jet.lang.resolve.DescriptorResolver;
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.List;
034 import java.util.Set;
035
036 public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRootImpl implements FunctionDescriptor {
037
038 protected List<TypeParameterDescriptor> typeParameters;
039 protected List<ValueParameterDescriptor> unsubstitutedValueParameters;
040 protected JetType unsubstitutedReturnType;
041 private ReceiverParameterDescriptor receiverParameter;
042 protected ReceiverParameterDescriptor expectedThisObject;
043
044 protected Modality modality;
045 protected Visibility visibility;
046 protected final Set<FunctionDescriptor> overriddenFunctions = Sets.newLinkedHashSet(); // LinkedHashSet is essential here
047 private final FunctionDescriptor original;
048 private final Kind kind;
049
050 protected FunctionDescriptorImpl(
051 @NotNull DeclarationDescriptor containingDeclaration,
052 @NotNull List<AnnotationDescriptor> annotations,
053 @NotNull Name name,
054 @NotNull Kind kind) {
055 super(containingDeclaration, annotations, name);
056 this.original = this;
057 this.kind = kind;
058 }
059
060 protected FunctionDescriptorImpl(
061 @NotNull DeclarationDescriptor containingDeclaration,
062 @NotNull FunctionDescriptor original,
063 @NotNull List<AnnotationDescriptor> annotations,
064 @NotNull Name name,
065 @NotNull Kind kind) {
066 super(containingDeclaration, annotations, name);
067 this.original = original;
068 this.kind = kind;
069 }
070
071 protected FunctionDescriptorImpl initialize(
072 @Nullable JetType receiverParameterType,
073 @Nullable ReceiverParameterDescriptor expectedThisObject,
074 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
075 @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
076 @Nullable JetType unsubstitutedReturnType,
077 @Nullable Modality modality,
078 @NotNull Visibility visibility) {
079 this.typeParameters = Lists.newArrayList(typeParameters);
080 this.unsubstitutedValueParameters = unsubstitutedValueParameters;
081 this.unsubstitutedReturnType = unsubstitutedReturnType;
082 this.modality = modality;
083 this.visibility = visibility;
084 this.receiverParameter = DescriptorResolver.resolveReceiverParameterFor(this, receiverParameterType);
085 this.expectedThisObject = expectedThisObject;
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 setReturnType(@NotNull JetType unsubstitutedReturnType) {
111 if (this.unsubstitutedReturnType != null) {
112 // TODO: uncomment and fix tests
113 //throw new IllegalStateException("returnType already set");
114 }
115 this.unsubstitutedReturnType = unsubstitutedReturnType;
116 }
117
118 @Nullable
119 @Override
120 public ReceiverParameterDescriptor getReceiverParameter() {
121 return receiverParameter;
122 }
123
124 @Nullable
125 @Override
126 public ReceiverParameterDescriptor getExpectedThisObject() {
127 return expectedThisObject;
128 }
129
130 @NotNull
131 @Override
132 public Set<? extends FunctionDescriptor> getOverriddenDescriptors() {
133 return overriddenFunctions;
134 }
135
136 @NotNull
137 @Override
138 public Modality getModality() {
139 return modality;
140 }
141
142 @NotNull
143 @Override
144 public Visibility getVisibility() {
145 return visibility;
146 }
147
148 @Override
149 public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
150 overriddenFunctions.add((FunctionDescriptor) overriddenFunction);
151 }
152
153 @Override
154 @NotNull
155 public List<TypeParameterDescriptor> getTypeParameters() {
156 return typeParameters;
157 }
158
159 @Override
160 @NotNull
161 public List<ValueParameterDescriptor> getValueParameters() {
162 return unsubstitutedValueParameters;
163 }
164
165 @Override
166 public JetType getReturnType() {
167 return unsubstitutedReturnType;
168 }
169
170 @NotNull
171 @Override
172 public FunctionDescriptor getOriginal() {
173 return original == this ? this : original.getOriginal();
174 }
175
176 @Override
177 public Kind getKind() {
178 return kind;
179 }
180
181 @Override
182 public final FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
183 if (originalSubstitutor.isEmpty()) {
184 return this;
185 }
186 return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility, true, true, getKind());
187 }
188
189 protected FunctionDescriptor doSubstitute(TypeSubstitutor originalSubstitutor,
190 DeclarationDescriptor newOwner, Modality newModality, Visibility newVisibility, boolean preserveOriginal, boolean copyOverrides, Kind kind) {
191 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, preserveOriginal, kind);
192
193 List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
194 TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
195
196 JetType substitutedReceiverParameterType = null;
197 if (receiverParameter != null) {
198 substitutedReceiverParameterType = substitutor.substitute(getReceiverParameter().getType(), Variance.IN_VARIANCE);
199 if (substitutedReceiverParameterType == null) {
200 return null;
201 }
202 }
203
204 ReceiverParameterDescriptor substitutedExpectedThis = null;
205 if (expectedThisObject != null) {
206 substitutedExpectedThis = expectedThisObject.substitute(substitutor);
207 if (substitutedExpectedThis == null) {
208 return null;
209 }
210 }
211
212 List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorUtil.getSubstitutedValueParameters(substitutedDescriptor, this, substitutor);
213 if (substitutedValueParameters == null) {
214 return null;
215 }
216
217 JetType substitutedReturnType = FunctionDescriptorUtil.getSubstitutedReturnType(this, substitutor);
218 if (substitutedReturnType == null) {
219 return null;
220 }
221
222 substitutedDescriptor.initialize(
223 substitutedReceiverParameterType,
224 substitutedExpectedThis,
225 substitutedTypeParameters,
226 substitutedValueParameters,
227 substitutedReturnType,
228 newModality,
229 newVisibility
230 );
231 if (copyOverrides) {
232 for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
233 OverridingUtil.bindOverride(substitutedDescriptor, overriddenFunction.substitute(substitutor));
234 }
235 }
236 return substitutedDescriptor;
237 }
238
239 protected abstract FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind);
240
241 @Override
242 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
243 return visitor.visitFunctionDescriptor(this, data);
244 }
245 }