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.DescriptorUtils;
027 import org.jetbrains.jet.lang.resolve.OverridingUtil;
028 import org.jetbrains.jet.lang.resolve.name.Name;
029 import org.jetbrains.jet.lang.types.DescriptorSubstitutor;
030 import org.jetbrains.jet.lang.types.JetType;
031 import org.jetbrains.jet.lang.types.TypeSubstitutor;
032 import org.jetbrains.jet.lang.types.Variance;
033
034 import java.util.Collections;
035 import java.util.List;
036 import java.util.Set;
037
038 public class PropertyDescriptorImpl extends VariableDescriptorImpl implements PropertyDescriptor {
039
040 private final Modality modality;
041 private Visibility visibility;
042 private final boolean isVar;
043 private final Set<PropertyDescriptor> overriddenProperties = Sets.newLinkedHashSet(); // LinkedHashSet is essential here
044 private final PropertyDescriptor original;
045 private final Kind kind;
046
047 private ReceiverParameterDescriptor expectedThisObject;
048 private ReceiverParameterDescriptor receiverParameter;
049 private List<TypeParameterDescriptor> typeParameters;
050 private PropertyGetterDescriptorImpl getter;
051 private PropertySetterDescriptor setter;
052
053 private PropertyDescriptorImpl(
054 @Nullable PropertyDescriptor original,
055 @NotNull DeclarationDescriptor containingDeclaration,
056 @NotNull List<AnnotationDescriptor> annotations,
057 @NotNull Modality modality,
058 @NotNull Visibility visibility,
059 boolean isVar,
060 @NotNull Name name,
061 @NotNull Kind kind
062 ) {
063 super(containingDeclaration, annotations, name);
064 this.isVar = isVar;
065 this.modality = modality;
066 this.visibility = visibility;
067 this.original = original == null ? this : original;
068 this.kind = kind;
069 }
070
071 public PropertyDescriptorImpl(
072 @NotNull DeclarationDescriptor containingDeclaration,
073 @NotNull List<AnnotationDescriptor> annotations,
074 @NotNull Modality modality,
075 @NotNull Visibility visibility,
076 boolean isVar,
077 @NotNull Name name,
078 @NotNull Kind kind
079 ) {
080 this(null, containingDeclaration, annotations, modality, visibility, isVar, name, kind);
081 }
082
083 public PropertyDescriptorImpl(
084 @NotNull DeclarationDescriptor containingDeclaration,
085 @NotNull List<AnnotationDescriptor> annotations,
086 @NotNull Modality modality,
087 @NotNull Visibility visibility,
088 boolean isVar,
089 @Nullable JetType receiverType,
090 @Nullable ReceiverParameterDescriptor expectedThisObject,
091 @NotNull Name name,
092 @NotNull JetType outType,
093 @NotNull Kind kind
094 ) {
095 this(containingDeclaration, annotations, modality, visibility, isVar, name, kind);
096 setType(outType, Collections.<TypeParameterDescriptor>emptyList(), expectedThisObject, receiverType);
097 }
098
099 public void setType(
100 @NotNull JetType outType,
101 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
102 @Nullable ReceiverParameterDescriptor expectedThisObject,
103 @Nullable JetType receiverType
104 ) {
105 ReceiverParameterDescriptor receiverParameter = DescriptorResolver.resolveReceiverParameterFor(this, receiverType);
106 setType(outType, typeParameters, expectedThisObject, receiverParameter);
107 }
108
109 public void setType(
110 @NotNull JetType outType,
111 @NotNull List<? extends TypeParameterDescriptor> typeParameters,
112 @Nullable ReceiverParameterDescriptor expectedThisObject,
113 @Nullable ReceiverParameterDescriptor receiverParameter
114 ) {
115 setOutType(outType);
116
117 this.typeParameters = Lists.newArrayList(typeParameters);
118
119 this.receiverParameter = receiverParameter;
120 this.expectedThisObject = expectedThisObject;
121 }
122
123 public void initialize(@Nullable PropertyGetterDescriptorImpl getter, @Nullable PropertySetterDescriptor setter) {
124 this.getter = getter;
125 this.setter = setter;
126 }
127
128 public void setVisibility(@NotNull Visibility visibility) {
129 this.visibility = visibility;
130 }
131
132 @NotNull
133 @Override
134 public List<TypeParameterDescriptor> getTypeParameters() {
135 return typeParameters;
136 }
137
138 @Override
139 @Nullable
140 public ReceiverParameterDescriptor getReceiverParameter() {
141 return receiverParameter;
142 }
143
144 @Nullable
145 @Override
146 public ReceiverParameterDescriptor getExpectedThisObject() {
147 return expectedThisObject;
148 }
149
150 @NotNull
151 @Override
152 public JetType getReturnType() {
153 return getType();
154 }
155
156 @Override
157 public boolean isVar() {
158 return isVar;
159 }
160
161 @NotNull
162 @Override
163 public Modality getModality() {
164 return modality;
165 }
166
167 @NotNull
168 @Override
169 public Visibility getVisibility() {
170 return visibility;
171 }
172
173 @Override
174 @Nullable
175 public PropertyGetterDescriptorImpl getGetter() {
176 return getter;
177 }
178
179 @Override
180 @Nullable
181 public PropertySetterDescriptor getSetter() {
182 return setter;
183 }
184
185 @Override
186 @NotNull
187 public List<PropertyAccessorDescriptor> getAccessors() {
188 List<PropertyAccessorDescriptor> r = Lists.newArrayListWithCapacity(2);
189 if (getter != null) {
190 r.add(getter);
191 }
192 if (setter != null) {
193 r.add(setter);
194 }
195 return r;
196 }
197
198 @Override
199 public PropertyDescriptor substitute(@NotNull TypeSubstitutor originalSubstitutor) {
200 if (originalSubstitutor.isEmpty()) {
201 return this;
202 }
203 return doSubstitute(originalSubstitutor, getContainingDeclaration(), modality, visibility, true, true, getKind());
204 }
205
206 private PropertyDescriptor doSubstitute(TypeSubstitutor originalSubstitutor,
207 DeclarationDescriptor newOwner, Modality newModality, Visibility newVisibility, boolean preserveOriginal, boolean copyOverrides, Kind kind) {
208 PropertyDescriptorImpl substitutedDescriptor = new PropertyDescriptorImpl(preserveOriginal ? getOriginal() : null, newOwner,
209 getAnnotations(), newModality, newVisibility, isVar(), getName(), kind);
210
211 List<TypeParameterDescriptor> substitutedTypeParameters = Lists.newArrayList();
212 TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(getTypeParameters(), originalSubstitutor, substitutedDescriptor, substitutedTypeParameters);
213
214 JetType originalOutType = getType();
215 JetType outType = substitutor.substitute(originalOutType, Variance.OUT_VARIANCE);
216 if (outType == null) {
217 return null; // TODO : tell the user that the property was projected out
218 }
219
220
221 ReceiverParameterDescriptor substitutedExpectedThisObject;
222 ReceiverParameterDescriptor expectedThisObject = getExpectedThisObject();
223 if (expectedThisObject != null) {
224 substitutedExpectedThisObject = expectedThisObject.substitute(substitutor);
225 if (substitutedExpectedThisObject == null) return null;
226 }
227 else {
228 substitutedExpectedThisObject = null;
229 }
230
231 JetType substitutedReceiverType;
232 if (receiverParameter != null) {
233 substitutedReceiverType = substitutor.substitute(receiverParameter.getType(), Variance.IN_VARIANCE);
234 if (substitutedReceiverType == null) return null;
235 }
236 else {
237 substitutedReceiverType = null;
238 }
239
240 substitutedDescriptor.setType(outType, substitutedTypeParameters, substitutedExpectedThisObject, substitutedReceiverType);
241
242 PropertyGetterDescriptorImpl newGetter = getter == null ? null : new PropertyGetterDescriptorImpl(
243 substitutedDescriptor, Lists.newArrayList(getter.getAnnotations()),
244 DescriptorUtils.convertModality(getter.getModality(), false), convertVisibility(getter.getVisibility(), newVisibility),
245 getter.hasBody(), getter.isDefault(), kind, getter.getOriginal());
246 if (newGetter != null) {
247 JetType returnType = getter.getReturnType();
248 newGetter.initialize(returnType != null ? substitutor.substitute(returnType, Variance.OUT_VARIANCE) : null);
249 }
250 PropertySetterDescriptorImpl newSetter = setter == null ? null : new PropertySetterDescriptorImpl(
251 substitutedDescriptor, Lists.newArrayList(setter.getAnnotations()), DescriptorUtils.convertModality(setter.getModality(), false),
252 convertVisibility(setter.getVisibility(), newVisibility), setter.hasBody(), setter.isDefault(), kind, setter.getOriginal());
253 if (newSetter != null) {
254 List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorUtil.getSubstitutedValueParameters(newSetter, setter, substitutor);
255 if (substitutedValueParameters == null) {
256 return null;
257 }
258 if (substitutedValueParameters.size() != 1) {
259 throw new IllegalStateException();
260 }
261 newSetter.initialize(substitutedValueParameters.get(0));
262 }
263
264 substitutedDescriptor.initialize(newGetter, newSetter);
265
266 if (copyOverrides) {
267 for (PropertyDescriptor propertyDescriptor : overriddenProperties) {
268 OverridingUtil.bindOverride(substitutedDescriptor, propertyDescriptor.substitute(substitutor));
269 }
270 }
271
272 return substitutedDescriptor;
273 }
274
275 @NotNull
276 private static Visibility convertVisibility(Visibility orig, Visibility candidate) {
277 if (candidate == Visibilities.INHERITED) {
278 return candidate;
279 }
280
281 Integer result = Visibilities.compare(orig, candidate);
282 return result != null && result < 0 ? candidate : orig;
283 }
284
285 @Override
286 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
287 return visitor.visitPropertyDescriptor(this, data);
288 }
289
290 @NotNull
291 @Override
292 public PropertyDescriptor getOriginal() {
293 return original == this ? this : original.getOriginal();
294 }
295
296 @Override
297 public Kind getKind() {
298 return kind;
299 }
300
301 @Override
302 public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overridden) {
303 overriddenProperties.add((PropertyDescriptorImpl) overridden);
304 }
305
306 @NotNull
307 @Override
308 public Set<? extends PropertyDescriptor> getOverriddenDescriptors() {
309 return overriddenProperties;
310 }
311
312 @NotNull
313 @Override
314 public PropertyDescriptor copy(DeclarationDescriptor newOwner, Modality modality, Visibility visibility, Kind kind, boolean copyOverrides) {
315 return doSubstitute(TypeSubstitutor.EMPTY, newOwner, modality, visibility, false, copyOverrides, kind);
316 }
317 }