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 org.jetbrains.annotations.NotNull; 021import org.jetbrains.annotations.Nullable; 022import org.jetbrains.jet.lang.descriptors.*; 023import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; 024import org.jetbrains.jet.lang.resolve.name.Name; 025import org.jetbrains.jet.lang.resolve.scopes.JetScope; 026import org.jetbrains.jet.lang.resolve.scopes.SubstitutingScope; 027import org.jetbrains.jet.lang.types.*; 028 029import java.util.Collection; 030import java.util.List; 031 032public class LazySubstitutingClassDescriptor implements ClassDescriptor { 033 034 private final ClassDescriptor original; 035 private final TypeSubstitutor originalSubstitutor; 036 private TypeSubstitutor newSubstitutor; 037 private List<TypeParameterDescriptor> typeParameters; 038 private TypeConstructor typeConstructor; 039 private JetType superclassType; 040 041 public LazySubstitutingClassDescriptor(ClassDescriptor descriptor, TypeSubstitutor substitutor) { 042 this.original = descriptor; 043 this.originalSubstitutor = substitutor; 044 } 045 046 private TypeSubstitutor getSubstitutor() { 047 if (newSubstitutor == null) { 048 if (originalSubstitutor.isEmpty()) { 049 newSubstitutor = originalSubstitutor; 050 } 051 else { 052 typeParameters = Lists.newArrayList(); 053 newSubstitutor = DescriptorSubstitutor.substituteTypeParameters(original.getTypeConstructor().getParameters(), originalSubstitutor, this, typeParameters); 054 } 055 } 056 return newSubstitutor; 057 } 058 059 @NotNull 060 @Override 061 public TypeConstructor getTypeConstructor() { 062 TypeConstructor originalTypeConstructor = original.getTypeConstructor(); 063 if (originalSubstitutor.isEmpty()) { 064 return originalTypeConstructor; 065 } 066 067 if (typeConstructor == null) { 068 TypeSubstitutor substitutor = getSubstitutor(); 069 070 Collection<JetType> supertypes = Lists.newArrayList(); 071 for (JetType supertype : originalTypeConstructor.getSupertypes()) { 072 supertypes.add(substitutor.substitute(supertype, Variance.INVARIANT)); 073 } 074 075 typeConstructor = new TypeConstructorImpl( 076 this, 077 originalTypeConstructor.getAnnotations(), 078 originalTypeConstructor.isSealed(), 079 originalTypeConstructor.toString(), 080 typeParameters, 081 supertypes 082 ); 083 } 084 085 return typeConstructor; 086 } 087 088 @NotNull 089 @Override 090 public JetScope getMemberScope(List<TypeProjection> typeArguments) { 091 JetScope memberScope = original.getMemberScope(typeArguments); 092 if (originalSubstitutor.isEmpty()) { 093 return memberScope; 094 } 095 return new SubstitutingScope(memberScope, getSubstitutor()); 096 } 097 098 @NotNull 099 @Override 100 public JetType getDefaultType() { 101 throw new UnsupportedOperationException(); // TODO 102 } 103 104 @NotNull 105 @Override 106 public ReceiverParameterDescriptor getThisAsReceiverParameter() { 107 throw new UnsupportedOperationException(); // TODO 108 } 109 110 @NotNull 111 @Override 112 public Collection<ConstructorDescriptor> getConstructors() { 113 Collection<ConstructorDescriptor> r = Lists.newArrayList(); 114 for (ConstructorDescriptor constructor : original.getConstructors()) { 115 r.add((ConstructorDescriptor) constructor.substitute(getSubstitutor())); 116 } 117 return r; 118 } 119 120 @Override 121 public List<AnnotationDescriptor> getAnnotations() { 122 return original.getAnnotations(); 123 } 124 125 @NotNull 126 @Override 127 public Name getName() { 128 return original.getName(); 129 } 130 131 @NotNull 132 @Override 133 public DeclarationDescriptor getOriginal() { 134 return original.getOriginal(); 135 } 136 137 @NotNull 138 @Override 139 public DeclarationDescriptor getContainingDeclaration() { 140 return original.getContainingDeclaration(); 141 } 142 143 @NotNull 144 @Override 145 public ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor) { 146 if (substitutor.isEmpty()) return this; 147 return new LazySubstitutingClassDescriptor(this, TypeSubstitutor.create(substitutor.getSubstitution(), getSubstitutor().getSubstitution())); 148 } 149 150 @Override 151 public JetType getClassObjectType() { 152 return original.getClassObjectType(); 153 } 154 155 @Override 156 public ClassDescriptor getClassObjectDescriptor() { 157 return original.getClassObjectDescriptor(); 158 } 159 160 @NotNull 161 @Override 162 public ClassKind getKind() { 163 return original.getKind(); 164 } 165 166 @Override 167 @NotNull 168 public Modality getModality() { 169 return original.getModality(); 170 } 171 172 @NotNull 173 @Override 174 public Visibility getVisibility() { 175 return original.getVisibility(); 176 } 177 178 @Override 179 public boolean isInner() { 180 return original.isInner(); 181 } 182 183 @Override 184 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) { 185 return visitor.visitClassDescriptor(this, data); 186 } 187 188 @Override 189 public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) { 190 throw new UnsupportedOperationException(); // TODO 191 } 192 193 @NotNull 194 @Override 195 public JetScope getUnsubstitutedInnerClassesScope() { 196 return original.getUnsubstitutedInnerClassesScope(); 197 } 198 199 @Nullable 200 @Override 201 public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() { 202 return original.getUnsubstitutedPrimaryConstructor(); 203 } 204}