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.OverridingUtil; 027import org.jetbrains.jet.lang.resolve.name.Name; 028import org.jetbrains.jet.lang.types.DescriptorSubstitutor; 029import org.jetbrains.jet.lang.types.JetType; 030import org.jetbrains.jet.lang.types.TypeSubstitutor; 031import org.jetbrains.jet.lang.types.Variance; 032 033import java.util.List; 034import java.util.Set; 035 036public 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}