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.descriptors.serialization;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer;
022 import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedSimpleFunctionDescriptor;
023 import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedTypeParameterDescriptor;
024 import org.jetbrains.jet.lang.descriptors.*;
025 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
026 import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
027 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl;
028 import org.jetbrains.jet.lang.descriptors.impl.*;
029 import org.jetbrains.jet.lang.resolve.DescriptorFactory;
030 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
031 import org.jetbrains.jet.lang.types.Variance;
032 import org.jetbrains.jet.storage.StorageManager;
033
034 import java.util.ArrayList;
035 import java.util.Collections;
036 import java.util.List;
037
038 import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable;
039 import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.TypeParameter;
040 import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE;
041 import static org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer.AnnotatedCallableKind;
042
043 public class DescriptorDeserializer {
044
045 @NotNull
046 public static DescriptorDeserializer create(
047 @NotNull StorageManager storageManager,
048 @NotNull DeclarationDescriptor containingDeclaration,
049 @NotNull NameResolver nameResolver,
050 @NotNull DescriptorFinder descriptorFinder,
051 @NotNull AnnotationDeserializer annotationDeserializer
052 ) {
053 return new DescriptorDeserializer(storageManager,
054 new TypeDeserializer(storageManager, null, nameResolver, descriptorFinder,
055 "Deserializer for " + containingDeclaration.getName(), NONE),
056 containingDeclaration, nameResolver, annotationDeserializer);
057 }
058
059 @NotNull
060 public static DescriptorDeserializer create(
061 @NotNull StorageManager storageManager,
062 @NotNull TypeDeserializer typeDeserializer,
063 @NotNull DeclarationDescriptor containingDeclaration,
064 @NotNull NameResolver nameResolver,
065 @NotNull AnnotationDeserializer annotationDeserializer
066 ) {
067 return new DescriptorDeserializer(storageManager, typeDeserializer, containingDeclaration, nameResolver, annotationDeserializer);
068 }
069
070 private final DeclarationDescriptor containingDeclaration;
071 private final NameResolver nameResolver;
072 private final TypeDeserializer typeDeserializer;
073 private final AnnotationDeserializer annotationDeserializer;
074
075 private final StorageManager storageManager;
076
077 private DescriptorDeserializer(
078 @NotNull StorageManager storageManager,
079 @NotNull TypeDeserializer typeDeserializer,
080 @NotNull DeclarationDescriptor containingDeclaration,
081 @NotNull NameResolver nameResolver,
082 @NotNull AnnotationDeserializer annotationDeserializer
083 ) {
084 this.storageManager = storageManager;
085 this.typeDeserializer = typeDeserializer;
086 this.containingDeclaration = containingDeclaration;
087 this.nameResolver = nameResolver;
088 this.annotationDeserializer = annotationDeserializer;
089 }
090
091 @NotNull
092 public TypeDeserializer getTypeDeserializer() {
093 return typeDeserializer;
094 }
095
096 @NotNull
097 public NameResolver getNameResolver() {
098 return nameResolver;
099 }
100
101 @NotNull
102 public DescriptorDeserializer createChildDeserializer(
103 @NotNull DeclarationDescriptor descriptor,
104 @NotNull final List<TypeParameter> typeParameterProtos,
105 @NotNull final List<TypeParameterDescriptor> typeParameters
106 ) {
107 TypeDeserializer childTypeDeserializer = new TypeDeserializer(
108 storageManager,
109 typeDeserializer, "Child deserializer for " + descriptor.getName(),
110 new TypeDeserializer.TypeParameterResolver() {
111 @NotNull
112 @Override
113 public List<DeserializedTypeParameterDescriptor> getTypeParameters(@NotNull TypeDeserializer typeDeserializer) {
114 List<DeserializedTypeParameterDescriptor> descriptors = typeParameters(typeParameterProtos, typeDeserializer);
115 typeParameters.addAll(descriptors);
116 return descriptors;
117 }
118 });
119 return create(storageManager, childTypeDeserializer, descriptor, nameResolver, annotationDeserializer);
120 }
121
122 @NotNull
123 public CallableMemberDescriptor loadCallable(@NotNull Callable proto) {
124 Callable.CallableKind callableKind = Flags.CALLABLE_KIND.get(proto.getFlags());
125 switch (callableKind) {
126 case FUN:
127 return loadFunction(proto);
128 case VAL:
129 case VAR:
130 return loadProperty(proto);
131 case CONSTRUCTOR:
132 return loadConstructor(proto);
133 }
134 throw new IllegalArgumentException("Unsupported callable kind: " + callableKind);
135 }
136
137 @NotNull
138 private PropertyDescriptor loadProperty(@NotNull Callable proto) {
139 int flags = proto.getFlags();
140
141 PropertyDescriptorImpl property = new PropertyDescriptorImpl(
142 containingDeclaration,
143 getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY),
144 modality(Flags.MODALITY.get(flags)),
145 visibility(Flags.VISIBILITY.get(flags)),
146 Flags.CALLABLE_KIND.get(flags) == Callable.CallableKind.VAR,
147 nameResolver.getName(proto.getName()),
148 memberKind(Flags.MEMBER_KIND.get(flags))
149 );
150
151 List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
152 DescriptorDeserializer local = createChildDeserializer(property, proto.getTypeParameterList(), typeParameters);
153 property.setType(
154 local.typeDeserializer.type(proto.getReturnType()),
155 typeParameters,
156 getExpectedThisObject(),
157 local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null)
158 );
159
160 PropertyGetterDescriptorImpl getter = null;
161 PropertySetterDescriptorImpl setter = null;
162
163 if (Flags.HAS_GETTER.get(flags)) {
164 int getterFlags = proto.getGetterFlags();
165 boolean isNotDefault = proto.hasGetterFlags() && Flags.IS_NOT_DEFAULT.get(getterFlags);
166 if (isNotDefault) {
167 getter = new PropertyGetterDescriptorImpl(
168 property, getAnnotations(proto, getterFlags, AnnotatedCallableKind.PROPERTY_GETTER),
169 modality(Flags.MODALITY.get(getterFlags)), visibility(Flags.VISIBILITY.get(getterFlags)),
170 isNotDefault, !isNotDefault, property.getKind()
171 );
172 }
173 else {
174 getter = DescriptorFactory.createDefaultGetter(property);
175 }
176 getter.initialize(property.getReturnType());
177 }
178
179 if (Flags.HAS_SETTER.get(flags)) {
180 int setterFlags = proto.getSetterFlags();
181 boolean isNotDefault = proto.hasSetterFlags() && Flags.IS_NOT_DEFAULT.get(setterFlags);
182 if (isNotDefault) {
183 setter = new PropertySetterDescriptorImpl(
184 property, getAnnotations(proto, setterFlags, AnnotatedCallableKind.PROPERTY_SETTER),
185 modality(Flags.MODALITY.get(setterFlags)), visibility(Flags.VISIBILITY.get(setterFlags)),
186 isNotDefault, !isNotDefault, property.getKind()
187 );
188 DescriptorDeserializer setterLocal = local.createChildDeserializer(setter, Collections.<TypeParameter>emptyList(),
189 Collections.<TypeParameterDescriptor>emptyList());
190 List<ValueParameterDescriptor> valueParameters = setterLocal.valueParameters(proto, AnnotatedCallableKind.PROPERTY_SETTER);
191 assert valueParameters.size() == 1 : "Property setter should have a single value parameter: " + setter;
192 setter.initialize(valueParameters.get(0));
193 }
194 else {
195 setter = DescriptorFactory.createDefaultSetter(property);
196 }
197 }
198
199 property.initialize(getter, setter);
200
201 return property;
202 }
203
204 @NotNull
205 private CallableMemberDescriptor loadFunction(@NotNull Callable proto) {
206 int flags = proto.getFlags();
207 DeserializedSimpleFunctionDescriptor function = new DeserializedSimpleFunctionDescriptor(
208 containingDeclaration, proto,
209 annotationDeserializer,
210 nameResolver
211 );
212 List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
213 DescriptorDeserializer local = createChildDeserializer(function, proto.getTypeParameterList(), typeParameters);
214 function.initialize(
215 local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null),
216 getExpectedThisObject(),
217 typeParameters,
218 local.valueParameters(proto, AnnotatedCallableKind.FUNCTION),
219 local.typeDeserializer.type(proto.getReturnType()),
220 modality(Flags.MODALITY.get(flags)),
221 visibility(Flags.VISIBILITY.get(flags))
222 );
223 return function;
224 }
225
226 @Nullable
227 private ReceiverParameterDescriptor getExpectedThisObject() {
228 return containingDeclaration instanceof ClassDescriptor
229 ? ((ClassDescriptor) containingDeclaration).getThisAsReceiverParameter() : null;
230 }
231
232 @NotNull
233 private CallableMemberDescriptor loadConstructor(@NotNull Callable proto) {
234 ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
235 ConstructorDescriptorImpl descriptor = new ConstructorDescriptorImpl(
236 classDescriptor,
237 getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION),
238 // TODO: primary
239 true);
240 List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
241 DescriptorDeserializer local = createChildDeserializer(descriptor, Collections.<TypeParameter>emptyList(), typeParameters);
242 descriptor.initialize(
243 classDescriptor.getTypeConstructor().getParameters(),
244 local.valueParameters(proto, AnnotatedCallableKind.FUNCTION),
245 visibility(Flags.VISIBILITY.get(proto.getFlags())),
246 DescriptorUtils.isConstructorOfStaticNestedClass(descriptor)
247 );
248 descriptor.setReturnType(local.typeDeserializer.type(proto.getReturnType()));
249 return descriptor;
250 }
251
252 @NotNull
253 private Annotations getAnnotations(@NotNull Callable proto, int flags, @NotNull AnnotatedCallableKind kind) {
254 return getAnnotations(containingDeclaration, proto, flags, kind, annotationDeserializer, nameResolver);
255 }
256
257 public static Annotations getAnnotations(
258 @NotNull DeclarationDescriptor containingDeclaration,
259 @NotNull Callable proto,
260 int flags,
261 @NotNull AnnotatedCallableKind kind,
262 @NotNull AnnotationDeserializer annotationDeserializer,
263 @NotNull NameResolver nameResolver
264 ) {
265 assert containingDeclaration instanceof ClassOrPackageFragmentDescriptor
266 : "Only members in classes or package fragments should be serialized: " + containingDeclaration;
267 return Flags.HAS_ANNOTATIONS.get(flags)
268 ? annotationDeserializer
269 .loadCallableAnnotations((ClassOrPackageFragmentDescriptor) containingDeclaration, proto, nameResolver, kind)
270 : Annotations.EMPTY;
271 }
272
273 public static CallableMemberDescriptor.Kind memberKind(Callable.MemberKind memberKind) {
274 switch (memberKind) {
275 case DECLARATION:
276 return CallableMemberDescriptor.Kind.DECLARATION;
277 case FAKE_OVERRIDE:
278 return CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
279 case DELEGATION:
280 return CallableMemberDescriptor.Kind.DELEGATION;
281 case SYNTHESIZED:
282 return CallableMemberDescriptor.Kind.SYNTHESIZED;
283 }
284 throw new IllegalArgumentException("Unknown member kind: " + memberKind);
285 }
286
287 @NotNull
288 public static Modality modality(@NotNull ProtoBuf.Modality modality) {
289 switch (modality) {
290 case FINAL:
291 return Modality.FINAL;
292 case OPEN:
293 return Modality.OPEN;
294 case ABSTRACT:
295 return Modality.ABSTRACT;
296 }
297 throw new IllegalArgumentException("Unknown modality: " + modality);
298 }
299
300 @NotNull
301 public static Visibility visibility(@NotNull ProtoBuf.Visibility visibility) {
302 switch (visibility) {
303 case INTERNAL:
304 return Visibilities.INTERNAL;
305 case PRIVATE:
306 return Visibilities.PRIVATE;
307 case PROTECTED:
308 return Visibilities.PROTECTED;
309 case PUBLIC:
310 return Visibilities.PUBLIC;
311 case EXTRA:
312 throw new UnsupportedOperationException("Extra visibilities are not supported yet"); // TODO
313 }
314 throw new IllegalArgumentException("Unknown visibility: " + visibility);
315 }
316
317 @NotNull
318 public static ClassKind classKind(@NotNull ProtoBuf.Class.Kind kind) {
319 switch (kind) {
320 case CLASS:
321 return ClassKind.CLASS;
322 case TRAIT:
323 return ClassKind.TRAIT;
324 case ENUM_CLASS:
325 return ClassKind.ENUM_CLASS;
326 case ENUM_ENTRY:
327 return ClassKind.ENUM_ENTRY;
328 case ANNOTATION_CLASS:
329 return ClassKind.ANNOTATION_CLASS;
330 case OBJECT:
331 return ClassKind.OBJECT;
332 case CLASS_OBJECT:
333 return ClassKind.CLASS_OBJECT;
334 }
335 throw new IllegalArgumentException("Unknown class kind: " + kind);
336 }
337
338 @NotNull
339 public List<DeserializedTypeParameterDescriptor> typeParameters(
340 @NotNull List<TypeParameter> protos,
341 @NotNull TypeDeserializer typeDeserializer
342 ) {
343 List<DeserializedTypeParameterDescriptor> result = new ArrayList<DeserializedTypeParameterDescriptor>(protos.size());
344 for (int i = 0; i < protos.size(); i++) {
345 TypeParameter proto = protos.get(i);
346 DeserializedTypeParameterDescriptor descriptor = new DeserializedTypeParameterDescriptor(
347 storageManager,
348 typeDeserializer,
349 proto,
350 containingDeclaration,
351 nameResolver.getName(proto.getName()),
352 variance(proto.getVariance()),
353 proto.getReified(),
354 i
355 );
356 result.add(descriptor);
357 }
358 return result;
359 }
360
361 private static Variance variance(TypeParameter.Variance proto) {
362 switch (proto) {
363 case IN:
364 return Variance.IN_VARIANCE;
365 case OUT:
366 return Variance.OUT_VARIANCE;
367 case INV:
368 return Variance.INVARIANT;
369 }
370 throw new IllegalStateException("Unknown projection: " + proto);
371 }
372
373 @NotNull
374 private List<ValueParameterDescriptor> valueParameters(@NotNull Callable callable, @NotNull AnnotatedCallableKind kind) {
375 DeclarationDescriptor containerOfCallable = containingDeclaration.getContainingDeclaration();
376 assert containerOfCallable instanceof ClassOrPackageFragmentDescriptor
377 : "Only members in classes or package fragments should be serialized: " + containerOfCallable;
378 ClassOrPackageFragmentDescriptor classOrPackage = (ClassOrPackageFragmentDescriptor) containerOfCallable;
379
380 List<Callable.ValueParameter> protos = callable.getValueParameterList();
381 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(protos.size());
382 for (int i = 0; i < protos.size(); i++) {
383 Callable.ValueParameter proto = protos.get(i);
384 result.add(new ValueParameterDescriptorImpl(
385 containingDeclaration,
386 i,
387 getAnnotations(classOrPackage, callable, kind, proto),
388 nameResolver.getName(proto.getName()),
389 typeDeserializer.type(proto.getType()),
390 Flags.DECLARES_DEFAULT_VALUE.get(proto.getFlags()),
391 typeDeserializer.typeOrNull(proto.hasVarargElementType() ? proto.getVarargElementType() : null))
392 );
393 }
394 return result;
395 }
396
397 @NotNull
398 private Annotations getAnnotations(
399 @NotNull ClassOrPackageFragmentDescriptor classOrPackage,
400 @NotNull Callable callable,
401 @NotNull AnnotatedCallableKind kind,
402 @NotNull Callable.ValueParameter valueParameter
403 ) {
404 return Flags.HAS_ANNOTATIONS.get(valueParameter.getFlags())
405 ? annotationDeserializer.loadValueParameterAnnotations(classOrPackage, callable, nameResolver, kind, valueParameter)
406 : Annotations.EMPTY;
407 }
408 }