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.impl.*;
027 import org.jetbrains.jet.lang.resolve.DescriptorFactory;
028 import org.jetbrains.jet.lang.resolve.DescriptorUtils;
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.AnnotationDeserializer.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 AnnotationDeserializer annotationDeserializer
050 ) {
051 return new DescriptorDeserializer(storageManager,
052 new TypeDeserializer(storageManager, null, nameResolver, descriptorFinder,
053 "Deserializer for " + containingDeclaration.getName(), NONE),
054 containingDeclaration, nameResolver, annotationDeserializer);
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 AnnotationDeserializer annotationDeserializer
064 ) {
065 return new DescriptorDeserializer(storageManager, typeDeserializer, containingDeclaration, nameResolver, annotationDeserializer);
066 }
067
068 private final DeclarationDescriptor containingDeclaration;
069 private final NameResolver nameResolver;
070 private final TypeDeserializer typeDeserializer;
071 private final AnnotationDeserializer annotationDeserializer;
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 AnnotationDeserializer annotationDeserializer
081 ) {
082 this.storageManager = storageManager;
083 this.typeDeserializer = typeDeserializer;
084 this.containingDeclaration = containingDeclaration;
085 this.nameResolver = nameResolver;
086 this.annotationDeserializer = annotationDeserializer;
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, annotationDeserializer);
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 Callable proto) {
137 int flags = proto.getFlags();
138
139 PropertyDescriptorImpl property = new PropertyDescriptorImpl(
140 containingDeclaration,
141 getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY),
142 modality(Flags.MODALITY.get(flags)),
143 visibility(Flags.VISIBILITY.get(flags)),
144 Flags.CALLABLE_KIND.get(flags) == Callable.CallableKind.VAR,
145 nameResolver.getName(proto.getName()),
146 memberKind(Flags.MEMBER_KIND.get(flags))
147 );
148
149 List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
150 DescriptorDeserializer local = createChildDeserializer(property, proto.getTypeParameterList(), typeParameters);
151 property.setType(
152 local.typeDeserializer.type(proto.getReturnType()),
153 typeParameters,
154 getExpectedThisObject(),
155 local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null)
156 );
157
158 PropertyGetterDescriptorImpl getter = null;
159 PropertySetterDescriptorImpl setter = null;
160
161 if (Flags.HAS_GETTER.get(flags)) {
162 int getterFlags = proto.getGetterFlags();
163 boolean isNotDefault = proto.hasGetterFlags() && Flags.IS_NOT_DEFAULT.get(getterFlags);
164 if (isNotDefault) {
165 getter = new PropertyGetterDescriptorImpl(
166 property, getAnnotations(proto, getterFlags, AnnotatedCallableKind.PROPERTY_GETTER),
167 modality(Flags.MODALITY.get(getterFlags)), visibility(Flags.VISIBILITY.get(getterFlags)),
168 isNotDefault, !isNotDefault, property.getKind()
169 );
170 }
171 else {
172 getter = DescriptorFactory.createDefaultGetter(property);
173 }
174 getter.initialize(property.getReturnType());
175 }
176
177 if (Flags.HAS_SETTER.get(flags)) {
178 int setterFlags = proto.getSetterFlags();
179 boolean isNotDefault = proto.hasSetterFlags() && Flags.IS_NOT_DEFAULT.get(setterFlags);
180 if (isNotDefault) {
181 setter = new PropertySetterDescriptorImpl(
182 property, getAnnotations(proto, setterFlags, AnnotatedCallableKind.PROPERTY_SETTER),
183 modality(Flags.MODALITY.get(setterFlags)), visibility(Flags.VISIBILITY.get(setterFlags)),
184 isNotDefault, !isNotDefault, property.getKind()
185 );
186 DescriptorDeserializer setterLocal = local.createChildDeserializer(setter, Collections.<TypeParameter>emptyList(),
187 Collections.<TypeParameterDescriptor>emptyList());
188 List<ValueParameterDescriptor> valueParameters = setterLocal.valueParameters(proto, AnnotatedCallableKind.PROPERTY_SETTER);
189 assert valueParameters.size() == 1 : "Property setter should have a single value parameter: " + setter;
190 setter.initialize(valueParameters.get(0));
191 }
192 else {
193 setter = DescriptorFactory.createDefaultSetter(property);
194 }
195 }
196
197 property.initialize(getter, setter);
198
199 return property;
200 }
201
202 @NotNull
203 private CallableMemberDescriptor loadFunction(@NotNull Callable proto) {
204 int flags = proto.getFlags();
205 DeserializedSimpleFunctionDescriptor function = new DeserializedSimpleFunctionDescriptor(
206 containingDeclaration, proto,
207 annotationDeserializer,
208 nameResolver
209 );
210 List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
211 DescriptorDeserializer local = createChildDeserializer(function, proto.getTypeParameterList(), typeParameters);
212 function.initialize(
213 local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null),
214 getExpectedThisObject(),
215 typeParameters,
216 local.valueParameters(proto, AnnotatedCallableKind.FUNCTION),
217 local.typeDeserializer.type(proto.getReturnType()),
218 modality(Flags.MODALITY.get(flags)),
219 visibility(Flags.VISIBILITY.get(flags))
220 );
221 return function;
222 }
223
224 @Nullable
225 private ReceiverParameterDescriptor getExpectedThisObject() {
226 return containingDeclaration instanceof ClassDescriptor
227 ? ((ClassDescriptor) containingDeclaration).getThisAsReceiverParameter() : null;
228 }
229
230 @NotNull
231 private CallableMemberDescriptor loadConstructor(@NotNull Callable proto) {
232 ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
233 ConstructorDescriptorImpl descriptor = new ConstructorDescriptorImpl(
234 classDescriptor,
235 getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION),
236 // TODO: primary
237 true);
238 List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
239 DescriptorDeserializer local = createChildDeserializer(descriptor, Collections.<TypeParameter>emptyList(), typeParameters);
240 descriptor.initialize(
241 classDescriptor.getTypeConstructor().getParameters(),
242 local.valueParameters(proto, AnnotatedCallableKind.FUNCTION),
243 visibility(Flags.VISIBILITY.get(proto.getFlags())),
244 DescriptorUtils.isConstructorOfStaticNestedClass(descriptor)
245 );
246 descriptor.setReturnType(local.typeDeserializer.type(proto.getReturnType()));
247 return descriptor;
248 }
249
250 @NotNull
251 private List<AnnotationDescriptor> getAnnotations(@NotNull Callable proto, int flags, @NotNull AnnotatedCallableKind kind) {
252 return getAnnotations(containingDeclaration, proto, flags, kind, annotationDeserializer, nameResolver);
253 }
254
255 public static List<AnnotationDescriptor> getAnnotations(
256 @NotNull DeclarationDescriptor containingDeclaration,
257 @NotNull Callable proto,
258 int flags,
259 @NotNull AnnotatedCallableKind kind,
260 @NotNull AnnotationDeserializer annotationDeserializer,
261 @NotNull NameResolver nameResolver
262 ) {
263 assert containingDeclaration instanceof ClassOrNamespaceDescriptor
264 : "Only members in classes or namespaces should be serialized: " + containingDeclaration;
265 return Flags.HAS_ANNOTATIONS.get(flags)
266 ? annotationDeserializer
267 .loadCallableAnnotations((ClassOrNamespaceDescriptor) containingDeclaration, proto, nameResolver, kind)
268 : Collections.<AnnotationDescriptor>emptyList();
269 }
270
271 public static CallableMemberDescriptor.Kind memberKind(Callable.MemberKind memberKind) {
272 switch (memberKind) {
273 case DECLARATION:
274 return CallableMemberDescriptor.Kind.DECLARATION;
275 case FAKE_OVERRIDE:
276 return CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
277 case DELEGATION:
278 return CallableMemberDescriptor.Kind.DELEGATION;
279 case SYNTHESIZED:
280 return CallableMemberDescriptor.Kind.SYNTHESIZED;
281 }
282 throw new IllegalArgumentException("Unknown member kind: " + memberKind);
283 }
284
285 @NotNull
286 public static Modality modality(@NotNull ProtoBuf.Modality modality) {
287 switch (modality) {
288 case FINAL:
289 return Modality.FINAL;
290 case OPEN:
291 return Modality.OPEN;
292 case ABSTRACT:
293 return Modality.ABSTRACT;
294 }
295 throw new IllegalArgumentException("Unknown modality: " + modality);
296 }
297
298 @NotNull
299 public static Visibility visibility(@NotNull ProtoBuf.Visibility visibility) {
300 switch (visibility) {
301 case INTERNAL:
302 return Visibilities.INTERNAL;
303 case PRIVATE:
304 return Visibilities.PRIVATE;
305 case PROTECTED:
306 return Visibilities.PROTECTED;
307 case PUBLIC:
308 return Visibilities.PUBLIC;
309 case EXTRA:
310 throw new UnsupportedOperationException("Extra visibilities are not supported yet"); // TODO
311 }
312 throw new IllegalArgumentException("Unknown visibility: " + visibility);
313 }
314
315 @NotNull
316 public static ClassKind classKind(@NotNull ProtoBuf.Class.Kind kind) {
317 switch (kind) {
318 case CLASS:
319 return ClassKind.CLASS;
320 case TRAIT:
321 return ClassKind.TRAIT;
322 case ENUM_CLASS:
323 return ClassKind.ENUM_CLASS;
324 case ENUM_ENTRY:
325 return ClassKind.ENUM_ENTRY;
326 case ANNOTATION_CLASS:
327 return ClassKind.ANNOTATION_CLASS;
328 case OBJECT:
329 return ClassKind.OBJECT;
330 case CLASS_OBJECT:
331 return ClassKind.CLASS_OBJECT;
332 }
333 throw new IllegalArgumentException("Unknown class kind: " + kind);
334 }
335
336 @NotNull
337 public List<DeserializedTypeParameterDescriptor> typeParameters(
338 @NotNull List<TypeParameter> protos,
339 @NotNull TypeDeserializer typeDeserializer
340 ) {
341 List<DeserializedTypeParameterDescriptor> result = new ArrayList<DeserializedTypeParameterDescriptor>(protos.size());
342 for (int i = 0; i < protos.size(); i++) {
343 TypeParameter proto = protos.get(i);
344 DeserializedTypeParameterDescriptor descriptor = new DeserializedTypeParameterDescriptor(
345 storageManager,
346 typeDeserializer,
347 proto,
348 containingDeclaration,
349 nameResolver.getName(proto.getName()),
350 variance(proto.getVariance()),
351 proto.getReified(),
352 i
353 );
354 result.add(descriptor);
355 }
356 return result;
357 }
358
359 private static Variance variance(TypeParameter.Variance proto) {
360 switch (proto) {
361 case IN:
362 return Variance.IN_VARIANCE;
363 case OUT:
364 return Variance.OUT_VARIANCE;
365 case INV:
366 return Variance.INVARIANT;
367 }
368 throw new IllegalStateException("Unknown projection: " + proto);
369 }
370
371 @NotNull
372 private List<ValueParameterDescriptor> valueParameters(@NotNull Callable callable, @NotNull AnnotatedCallableKind kind) {
373 DeclarationDescriptor containerOfCallable = containingDeclaration.getContainingDeclaration();
374 assert containerOfCallable instanceof ClassOrNamespaceDescriptor
375 : "Only members in classes or namespaces should be serialized: " + containerOfCallable;
376 ClassOrNamespaceDescriptor classOrNamespace = (ClassOrNamespaceDescriptor) containerOfCallable;
377
378 List<Callable.ValueParameter> protos = callable.getValueParameterList();
379 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(protos.size());
380 for (int i = 0; i < protos.size(); i++) {
381 Callable.ValueParameter proto = protos.get(i);
382 result.add(new ValueParameterDescriptorImpl(
383 containingDeclaration,
384 i,
385 getAnnotations(classOrNamespace, callable, kind, proto),
386 nameResolver.getName(proto.getName()),
387 typeDeserializer.type(proto.getType()),
388 Flags.DECLARES_DEFAULT_VALUE.get(proto.getFlags()),
389 typeDeserializer.typeOrNull(proto.hasVarargElementType() ? proto.getVarargElementType() : null))
390 );
391 }
392 return result;
393 }
394
395 @NotNull
396 private List<AnnotationDescriptor> getAnnotations(
397 @NotNull ClassOrNamespaceDescriptor classOrNamespace,
398 @NotNull Callable callable,
399 @NotNull AnnotatedCallableKind kind,
400 @NotNull Callable.ValueParameter valueParameter
401 ) {
402 return Flags.HAS_ANNOTATIONS.get(valueParameter.getFlags())
403 ? annotationDeserializer.loadValueParameterAnnotations(classOrNamespace, callable, nameResolver, kind, valueParameter)
404 : Collections.<AnnotationDescriptor>emptyList();
405 }
406 }