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