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.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 List<AnnotationDescriptor> 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 List<AnnotationDescriptor> 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 JetType getReturnType() {
169 return unsubstitutedReturnType;
170 }
171
172 @NotNull
173 @Override
174 public FunctionDescriptor getOriginal() {
175 return original == this ? this : original.getOriginal();
176 }
177
178 @Override
179 public Kind getKind() {
180 return kind;
181 }
182
183 @Override
184 public final FunctionDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
185 if (originalSubstitutor.isEmpty()) {
186 return this;
187 }
188 return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility, true, true, getKind());
189 }
190
191 protected FunctionDescriptor doSubstitute(TypeSubstitutor originalSubstitutor,
192 DeclarationDescriptor newOwner, Modality newModality, Visibility newVisibility, boolean preserveOriginal, boolean copyOverrides, Kind kind) {
193 FunctionDescriptorImpl substitutedDescriptor = createSubstitutedCopy(newOwner, preserveOriginal, kind);
194
195 List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
196 TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
197
198 JetType substitutedReceiverParameterType = null;
199 if (receiverParameter != null) {
200 substitutedReceiverParameterType = substitutor.substitute(getReceiverParameter().getType(), Variance.IN_VARIANCE);
201 if (substitutedReceiverParameterType == null) {
202 return null;
203 }
204 }
205
206 ReceiverParameterDescriptor substitutedExpectedThis = null;
207 if (expectedThisObject != null) {
208 substitutedExpectedThis = expectedThisObject.substitute(substitutor);
209 if (substitutedExpectedThis == null) {
210 return null;
211 }
212 }
213
214 List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(substitutedDescriptor, this, substitutor);
215 if (substitutedValueParameters == null) {
216 return null;
217 }
218
219 JetType substitutedReturnType = substitutor.substitute(getReturnType(), Variance.OUT_VARIANCE);
220 if (substitutedReturnType == null) {
221 return null;
222 }
223
224 substitutedDescriptor.initialize(
225 substitutedReceiverParameterType,
226 substitutedExpectedThis,
227 substitutedTypeParameters,
228 substitutedValueParameters,
229 substitutedReturnType,
230 newModality,
231 newVisibility
232 );
233 if (copyOverrides) {
234 for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
235 OverridingUtil.bindOverride(substitutedDescriptor, overriddenFunction.substitute(substitutor));
236 }
237 }
238 return substitutedDescriptor;
239 }
240
241 protected abstract FunctionDescriptorImpl createSubstitutedCopy(DeclarationDescriptor newOwner, boolean preserveOriginal, Kind kind);
242
243 @Override
244 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
245 return visitor.visitFunctionDescriptor(this, data);
246 }
247
248 @Nullable
249 public static List<ValueParameterDescriptor> getSubstitutedValueParameters(FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeSubstitutor substitutor) {
250 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>();
251 List<ValueParameterDescriptor> unsubstitutedValueParameters = functionDescriptor.getValueParameters();
252 for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
253 // TODO : Lazy?
254 JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE);
255 JetType varargElementType = unsubstitutedValueParameter.getVarargElementType();
256 JetType substituteVarargElementType = varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
257 if (substitutedType == null) return null;
258 result.add(new ValueParameterDescriptorImpl(
259 substitutedDescriptor,
260 unsubstitutedValueParameter,
261 unsubstitutedValueParameter.getAnnotations(),
262 substitutedType,
263 substituteVarargElementType
264 ));
265 }
266 return result;
267 }
268 }