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