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 017package org.jetbrains.jet.lang.descriptors.impl; 018 019import com.google.common.collect.Lists; 020import com.google.common.collect.Sets; 021import org.jetbrains.annotations.NotNull; 022import org.jetbrains.annotations.Nullable; 023import org.jetbrains.jet.lang.descriptors.*; 024import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; 025import org.jetbrains.jet.lang.resolve.DescriptorResolver; 026import org.jetbrains.jet.lang.resolve.DescriptorUtils; 027import org.jetbrains.jet.lang.resolve.OverridingUtil; 028import org.jetbrains.jet.lang.resolve.name.Name; 029import org.jetbrains.jet.lang.types.DescriptorSubstitutor; 030import org.jetbrains.jet.lang.types.JetType; 031import org.jetbrains.jet.lang.types.TypeSubstitutor; 032import org.jetbrains.jet.lang.types.Variance; 033 034import java.util.Collections; 035import java.util.List; 036import java.util.Set; 037 038public 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}