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