001 /* 002 * Copyright 2010-2015 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.kotlin.serialization; 018 019 import com.google.protobuf.MessageLite; 020 import kotlin.collections.CollectionsKt; 021 import kotlin.jvm.functions.Function1; 022 import org.jetbrains.annotations.NotNull; 023 import org.jetbrains.annotations.Nullable; 024 import org.jetbrains.kotlin.builtins.KotlinBuiltIns; 025 import org.jetbrains.kotlin.descriptors.*; 026 import org.jetbrains.kotlin.descriptors.annotations.Annotated; 027 import org.jetbrains.kotlin.name.Name; 028 import org.jetbrains.kotlin.resolve.DescriptorUtils; 029 import org.jetbrains.kotlin.resolve.MemberComparator; 030 import org.jetbrains.kotlin.resolve.constants.ConstantValue; 031 import org.jetbrains.kotlin.resolve.constants.NullValue; 032 import org.jetbrains.kotlin.types.*; 033 import org.jetbrains.kotlin.utils.ExceptionUtilsKt; 034 import org.jetbrains.kotlin.utils.Interner; 035 036 import java.io.ByteArrayOutputStream; 037 import java.io.IOException; 038 import java.util.ArrayList; 039 import java.util.Collection; 040 import java.util.Collections; 041 import java.util.List; 042 043 import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry; 044 045 public class DescriptorSerializer { 046 private final DeclarationDescriptor containingDeclaration; 047 private final Interner<TypeParameterDescriptor> typeParameters; 048 private final SerializerExtension extension; 049 private final MutableTypeTable typeTable; 050 private final boolean serializeTypeTableToFunction; 051 052 private DescriptorSerializer( 053 @Nullable DeclarationDescriptor containingDeclaration, 054 @NotNull Interner<TypeParameterDescriptor> typeParameters, 055 @NotNull SerializerExtension extension, 056 @NotNull MutableTypeTable typeTable, 057 boolean serializeTypeTableToFunction 058 ) { 059 this.containingDeclaration = containingDeclaration; 060 this.typeParameters = typeParameters; 061 this.extension = extension; 062 this.typeTable = typeTable; 063 this.serializeTypeTableToFunction = serializeTypeTableToFunction; 064 } 065 066 @NotNull 067 public byte[] serialize(@NotNull MessageLite message) { 068 try { 069 ByteArrayOutputStream result = new ByteArrayOutputStream(); 070 getStringTable().serializeTo(result); 071 message.writeTo(result); 072 return result.toByteArray(); 073 } 074 catch (IOException e) { 075 throw ExceptionUtilsKt.rethrow(e); 076 } 077 } 078 079 @NotNull 080 public static DescriptorSerializer createTopLevel(@NotNull SerializerExtension extension) { 081 return new DescriptorSerializer(null, new Interner<TypeParameterDescriptor>(), extension, new MutableTypeTable(), false); 082 } 083 084 @NotNull 085 public static DescriptorSerializer createForLambda(@NotNull SerializerExtension extension) { 086 return new DescriptorSerializer(null, new Interner<TypeParameterDescriptor>(), extension, new MutableTypeTable(), true); 087 } 088 089 @NotNull 090 public static DescriptorSerializer create(@NotNull ClassDescriptor descriptor, @NotNull SerializerExtension extension) { 091 DeclarationDescriptor container = descriptor.getContainingDeclaration(); 092 DescriptorSerializer parentSerializer = 093 container instanceof ClassDescriptor 094 ? create((ClassDescriptor) container, extension) 095 : createTopLevel(extension); 096 097 // Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always 098 // serializing outer classes before nested classes. 099 // Otherwise our interner can get wrong ids because we may serialize classes in any order. 100 DescriptorSerializer serializer = new DescriptorSerializer( 101 descriptor, 102 new Interner<TypeParameterDescriptor>(parentSerializer.typeParameters), 103 parentSerializer.extension, 104 new MutableTypeTable(), 105 false 106 ); 107 for (TypeParameterDescriptor typeParameter : descriptor.getDeclaredTypeParameters()) { 108 serializer.typeParameters.intern(typeParameter); 109 } 110 return serializer; 111 } 112 113 @NotNull 114 private DescriptorSerializer createChildSerializer(@NotNull CallableDescriptor callable) { 115 return new DescriptorSerializer(callable, new Interner<TypeParameterDescriptor>(typeParameters), extension, typeTable, false); 116 } 117 118 @NotNull 119 public StringTable getStringTable() { 120 return extension.getStringTable(); 121 } 122 123 private boolean useTypeTable() { 124 return extension.shouldUseTypeTable(); 125 } 126 127 @NotNull 128 public ProtoBuf.Class.Builder classProto(@NotNull ClassDescriptor classDescriptor) { 129 ProtoBuf.Class.Builder builder = ProtoBuf.Class.newBuilder(); 130 131 int flags = Flags.getClassFlags(hasAnnotations(classDescriptor), classDescriptor.getVisibility(), classDescriptor.getModality(), 132 classDescriptor.getKind(), classDescriptor.isInner(), classDescriptor.isCompanionObject(), 133 classDescriptor.isData()); 134 if (flags != builder.getFlags()) { 135 builder.setFlags(flags); 136 } 137 138 builder.setFqName(getClassId(classDescriptor)); 139 140 for (TypeParameterDescriptor typeParameterDescriptor : classDescriptor.getDeclaredTypeParameters()) { 141 builder.addTypeParameter(typeParameter(typeParameterDescriptor)); 142 } 143 144 if (!KotlinBuiltIns.isSpecialClassWithNoSupertypes(classDescriptor)) { 145 // Special classes (Any, Nothing) have no supertypes 146 for (KotlinType supertype : classDescriptor.getTypeConstructor().getSupertypes()) { 147 if (useTypeTable()) { 148 builder.addSupertypeId(typeId(supertype)); 149 } 150 else { 151 builder.addSupertype(type(supertype)); 152 } 153 } 154 } 155 156 for (ConstructorDescriptor descriptor : classDescriptor.getConstructors()) { 157 builder.addConstructor(constructorProto(descriptor)); 158 } 159 160 for (DeclarationDescriptor descriptor : sort(DescriptorUtils.getAllDescriptors(classDescriptor.getDefaultType().getMemberScope()))) { 161 if (descriptor instanceof CallableMemberDescriptor) { 162 CallableMemberDescriptor member = (CallableMemberDescriptor) descriptor; 163 if (member.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue; 164 165 if (descriptor instanceof PropertyDescriptor) { 166 builder.addProperty(propertyProto((PropertyDescriptor) descriptor)); 167 } 168 else if (descriptor instanceof FunctionDescriptor) { 169 builder.addFunction(functionProto((FunctionDescriptor) descriptor)); 170 } 171 } 172 } 173 174 for (DeclarationDescriptor descriptor : sort(DescriptorUtils.getAllDescriptors(classDescriptor.getUnsubstitutedInnerClassesScope()))) { 175 int name = getSimpleNameIndex(descriptor.getName()); 176 if (isEnumEntry(descriptor)) { 177 builder.addEnumEntry(enumEntryProto((ClassDescriptor) descriptor)); 178 } 179 else { 180 builder.addNestedClassName(name); 181 } 182 } 183 184 ClassDescriptor companionObjectDescriptor = classDescriptor.getCompanionObjectDescriptor(); 185 if (companionObjectDescriptor != null) { 186 builder.setCompanionObjectName(getSimpleNameIndex(companionObjectDescriptor.getName())); 187 } 188 189 ProtoBuf.TypeTable typeTableProto = typeTable.serialize(); 190 if (typeTableProto != null) { 191 builder.setTypeTable(typeTableProto); 192 } 193 194 extension.serializeClass(classDescriptor, builder); 195 196 return builder; 197 } 198 199 @NotNull 200 public ProtoBuf.Property.Builder propertyProto(@NotNull PropertyDescriptor descriptor) { 201 ProtoBuf.Property.Builder builder = ProtoBuf.Property.newBuilder(); 202 203 DescriptorSerializer local = createChildSerializer(descriptor); 204 205 boolean hasGetter = false; 206 boolean hasSetter = false; 207 boolean lateInit = descriptor.isLateInit(); 208 boolean isConst = descriptor.isConst(); 209 210 ConstantValue<?> compileTimeConstant = descriptor.getCompileTimeInitializer(); 211 boolean hasConstant = !(compileTimeConstant == null || compileTimeConstant instanceof NullValue); 212 213 boolean hasAnnotations = !descriptor.getAnnotations().getAllAnnotations().isEmpty(); 214 215 int propertyFlags = Flags.getAccessorFlags( 216 hasAnnotations, 217 descriptor.getVisibility(), 218 descriptor.getModality(), 219 false, 220 false 221 ); 222 223 PropertyGetterDescriptor getter = descriptor.getGetter(); 224 if (getter != null) { 225 hasGetter = true; 226 int accessorFlags = getAccessorFlags(getter); 227 if (accessorFlags != propertyFlags) { 228 builder.setGetterFlags(accessorFlags); 229 } 230 } 231 232 PropertySetterDescriptor setter = descriptor.getSetter(); 233 if (setter != null) { 234 hasSetter = true; 235 int accessorFlags = getAccessorFlags(setter); 236 if (accessorFlags != propertyFlags) { 237 builder.setSetterFlags(accessorFlags); 238 } 239 240 if (!setter.isDefault()) { 241 DescriptorSerializer setterLocal = local.createChildSerializer(setter); 242 for (ValueParameterDescriptor valueParameterDescriptor : setter.getValueParameters()) { 243 builder.setSetterValueParameter(setterLocal.valueParameter(valueParameterDescriptor)); 244 } 245 } 246 } 247 248 int flags = Flags.getPropertyFlags( 249 hasAnnotations, descriptor.getVisibility(), descriptor.getModality(), descriptor.getKind(), descriptor.isVar(), 250 hasGetter, hasSetter, hasConstant, isConst, lateInit 251 ); 252 if (flags != builder.getFlags()) { 253 builder.setFlags(flags); 254 } 255 256 builder.setName(getSimpleNameIndex(descriptor.getName())); 257 258 if (useTypeTable()) { 259 builder.setReturnTypeId(local.typeId(descriptor.getType())); 260 } 261 else { 262 builder.setReturnType(local.type(descriptor.getType())); 263 } 264 265 for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) { 266 builder.addTypeParameter(local.typeParameter(typeParameterDescriptor)); 267 } 268 269 ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter(); 270 if (receiverParameter != null) { 271 if (useTypeTable()) { 272 builder.setReceiverTypeId(local.typeId(receiverParameter.getType())); 273 } 274 else { 275 builder.setReceiverType(local.type(receiverParameter.getType())); 276 } 277 } 278 279 extension.serializeProperty(descriptor, builder); 280 281 return builder; 282 } 283 284 @NotNull 285 public ProtoBuf.Function.Builder functionProto(@NotNull FunctionDescriptor descriptor) { 286 ProtoBuf.Function.Builder builder = ProtoBuf.Function.newBuilder(); 287 288 DescriptorSerializer local = createChildSerializer(descriptor); 289 290 int flags = Flags.getFunctionFlags( 291 hasAnnotations(descriptor), descriptor.getVisibility(), descriptor.getModality(), descriptor.getKind(), 292 descriptor.isOperator(), descriptor.isInfix(), descriptor.isInline(), descriptor.isTailrec(), 293 descriptor.isExternal() 294 ); 295 if (flags != builder.getFlags()) { 296 builder.setFlags(flags); 297 } 298 299 builder.setName(getSimpleNameIndex(descriptor.getName())); 300 301 if (useTypeTable()) { 302 //noinspection ConstantConditions 303 builder.setReturnTypeId(local.typeId(descriptor.getReturnType())); 304 } 305 else { 306 //noinspection ConstantConditions 307 builder.setReturnType(local.type(descriptor.getReturnType())); 308 } 309 310 for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) { 311 builder.addTypeParameter(local.typeParameter(typeParameterDescriptor)); 312 } 313 314 ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter(); 315 if (receiverParameter != null) { 316 if (useTypeTable()) { 317 builder.setReceiverTypeId(local.typeId(receiverParameter.getType())); 318 } 319 else { 320 builder.setReceiverType(local.type(receiverParameter.getType())); 321 } 322 } 323 324 for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) { 325 builder.addValueParameter(local.valueParameter(valueParameterDescriptor)); 326 } 327 328 if (serializeTypeTableToFunction) { 329 ProtoBuf.TypeTable typeTableProto = typeTable.serialize(); 330 if (typeTableProto != null) { 331 builder.setTypeTable(typeTableProto); 332 } 333 } 334 335 extension.serializeFunction(descriptor, builder); 336 337 return builder; 338 } 339 340 @NotNull 341 public ProtoBuf.Constructor.Builder constructorProto(@NotNull ConstructorDescriptor descriptor) { 342 ProtoBuf.Constructor.Builder builder = ProtoBuf.Constructor.newBuilder(); 343 344 DescriptorSerializer local = createChildSerializer(descriptor); 345 346 int flags = Flags.getConstructorFlags(hasAnnotations(descriptor), descriptor.getVisibility(), !descriptor.isPrimary()); 347 if (flags != builder.getFlags()) { 348 builder.setFlags(flags); 349 } 350 351 for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) { 352 builder.addValueParameter(local.valueParameter(valueParameterDescriptor)); 353 } 354 355 extension.serializeConstructor(descriptor, builder); 356 357 return builder; 358 } 359 360 @NotNull 361 public ProtoBuf.EnumEntry.Builder enumEntryProto(@NotNull ClassDescriptor descriptor) { 362 ProtoBuf.EnumEntry.Builder builder = ProtoBuf.EnumEntry.newBuilder(); 363 builder.setName(getSimpleNameIndex(descriptor.getName())); 364 extension.serializeEnumEntry(descriptor, builder); 365 return builder; 366 } 367 368 private static int getAccessorFlags(@NotNull PropertyAccessorDescriptor accessor) { 369 return Flags.getAccessorFlags( 370 hasAnnotations(accessor), 371 accessor.getVisibility(), 372 accessor.getModality(), 373 !accessor.isDefault(), 374 accessor.isExternal() 375 ); 376 } 377 378 @NotNull 379 private ProtoBuf.ValueParameter.Builder valueParameter(@NotNull ValueParameterDescriptor descriptor) { 380 ProtoBuf.ValueParameter.Builder builder = ProtoBuf.ValueParameter.newBuilder(); 381 382 int flags = Flags.getValueParameterFlags(hasAnnotations(descriptor), descriptor.declaresDefaultValue(), 383 descriptor.isCrossinline(), descriptor.isNoinline()); 384 if (flags != builder.getFlags()) { 385 builder.setFlags(flags); 386 } 387 388 builder.setName(getSimpleNameIndex(descriptor.getName())); 389 390 if (useTypeTable()) { 391 builder.setTypeId(typeId(descriptor.getType())); 392 } 393 else { 394 builder.setType(type(descriptor.getType())); 395 } 396 397 KotlinType varargElementType = descriptor.getVarargElementType(); 398 if (varargElementType != null) { 399 if (useTypeTable()) { 400 builder.setVarargElementTypeId(typeId(varargElementType)); 401 } 402 else { 403 builder.setVarargElementType(type(varargElementType)); 404 } 405 } 406 407 extension.serializeValueParameter(descriptor, builder); 408 409 return builder; 410 } 411 412 private ProtoBuf.TypeParameter.Builder typeParameter(TypeParameterDescriptor typeParameter) { 413 ProtoBuf.TypeParameter.Builder builder = ProtoBuf.TypeParameter.newBuilder(); 414 415 builder.setId(getTypeParameterId(typeParameter)); 416 417 builder.setName(getSimpleNameIndex(typeParameter.getName())); 418 419 if (typeParameter.isReified() != builder.getReified()) { 420 builder.setReified(typeParameter.isReified()); 421 } 422 423 ProtoBuf.TypeParameter.Variance variance = variance(typeParameter.getVariance()); 424 if (variance != builder.getVariance()) { 425 builder.setVariance(variance); 426 } 427 extension.serializeTypeParameter(typeParameter, builder); 428 429 List<KotlinType> upperBounds = typeParameter.getUpperBounds(); 430 if (upperBounds.size() == 1 && KotlinBuiltIns.isDefaultBound(CollectionsKt.single(upperBounds))) return builder; 431 432 for (KotlinType upperBound : upperBounds) { 433 if (useTypeTable()) { 434 builder.addUpperBoundId(typeId(upperBound)); 435 } 436 else { 437 builder.addUpperBound(type(upperBound)); 438 } 439 } 440 441 return builder; 442 } 443 444 private static ProtoBuf.TypeParameter.Variance variance(Variance variance) { 445 switch (variance) { 446 case INVARIANT: 447 return ProtoBuf.TypeParameter.Variance.INV; 448 case IN_VARIANCE: 449 return ProtoBuf.TypeParameter.Variance.IN; 450 case OUT_VARIANCE: 451 return ProtoBuf.TypeParameter.Variance.OUT; 452 } 453 throw new IllegalStateException("Unknown variance: " + variance); 454 } 455 456 private int typeId(@NotNull KotlinType type) { 457 return typeTable.get(type(type)); 458 } 459 460 @NotNull 461 private ProtoBuf.Type.Builder type(@NotNull KotlinType type) { 462 ProtoBuf.Type.Builder builder = ProtoBuf.Type.newBuilder(); 463 464 if (type.isError()) { 465 extension.serializeErrorType(type, builder); 466 return builder; 467 } 468 469 if (FlexibleTypesKt.isFlexible(type)) { 470 Flexibility flexibility = FlexibleTypesKt.flexibility(type); 471 472 ProtoBuf.Type.Builder lowerBound = type(flexibility.getLowerBound()); 473 lowerBound.setFlexibleTypeCapabilitiesId(getStringTable().getStringIndex(flexibility.getExtraCapabilities().getId())); 474 if (useTypeTable()) { 475 lowerBound.setFlexibleUpperBoundId(typeId(flexibility.getUpperBound())); 476 } 477 else { 478 lowerBound.setFlexibleUpperBound(type(flexibility.getUpperBound())); 479 } 480 return lowerBound; 481 } 482 483 ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); 484 if (descriptor instanceof ClassDescriptor) { 485 PossiblyInnerType possiblyInnerType = TypeParameterUtilsKt.buildPossiblyInnerType(type); 486 assert possiblyInnerType != null : "possiblyInnerType should not be null in case of class"; 487 488 fillFromPossiblyInnerType(builder, possiblyInnerType); 489 490 } 491 if (descriptor instanceof TypeParameterDescriptor) { 492 TypeParameterDescriptor typeParameter = (TypeParameterDescriptor) descriptor; 493 if (typeParameter.getContainingDeclaration() == containingDeclaration) { 494 builder.setTypeParameterName(getSimpleNameIndex(typeParameter.getName())); 495 } 496 else { 497 builder.setTypeParameter(getTypeParameterId(typeParameter)); 498 } 499 500 assert type.getArguments().isEmpty() : "Found arguments for type constructor build on type parameter: " + descriptor; 501 } 502 503 if (type.isMarkedNullable() != builder.getNullable()) { 504 builder.setNullable(type.isMarkedNullable()); 505 } 506 507 extension.serializeType(type, builder); 508 509 return builder; 510 } 511 512 private void fillFromPossiblyInnerType( 513 @NotNull ProtoBuf.Type.Builder builder, 514 @NotNull PossiblyInnerType type 515 ) { 516 builder.setClassName(getClassId(type.getClassDescriptor())); 517 518 for (TypeProjection projection : type.getArguments()) { 519 builder.addArgument(typeArgument(projection)); 520 } 521 522 if (type.getOuterType() != null) { 523 ProtoBuf.Type.Builder outerBuilder = ProtoBuf.Type.newBuilder(); 524 fillFromPossiblyInnerType(outerBuilder, type.getOuterType()); 525 if (useTypeTable()) { 526 builder.setOuterTypeId(typeTable.get(outerBuilder)); 527 } 528 else { 529 builder.setOuterType(outerBuilder); 530 } 531 532 } 533 } 534 535 @NotNull 536 private ProtoBuf.Type.Argument.Builder typeArgument(@NotNull TypeProjection typeProjection) { 537 ProtoBuf.Type.Argument.Builder builder = ProtoBuf.Type.Argument.newBuilder(); 538 539 if (typeProjection.isStarProjection()) { 540 builder.setProjection(ProtoBuf.Type.Argument.Projection.STAR); 541 } 542 else { 543 ProtoBuf.Type.Argument.Projection projection = projection(typeProjection.getProjectionKind()); 544 545 if (projection != builder.getProjection()) { 546 builder.setProjection(projection); 547 } 548 549 if (useTypeTable()) { 550 builder.setTypeId(typeId(typeProjection.getType())); 551 } 552 else { 553 builder.setType(type(typeProjection.getType())); 554 } 555 } 556 557 return builder; 558 } 559 560 @NotNull 561 public ProtoBuf.Package.Builder packageProto(@NotNull Collection<PackageFragmentDescriptor> fragments) { 562 return packageProto(fragments, null); 563 } 564 565 @NotNull 566 public ProtoBuf.Package.Builder packageProto( 567 @NotNull Collection<PackageFragmentDescriptor> fragments, 568 @Nullable Function1<DeclarationDescriptor, Boolean> skip 569 ) { 570 ProtoBuf.Package.Builder builder = ProtoBuf.Package.newBuilder(); 571 572 Collection<DeclarationDescriptor> members = new ArrayList<DeclarationDescriptor>(); 573 for (PackageFragmentDescriptor fragment : fragments) { 574 members.addAll(DescriptorUtils.getAllDescriptors(fragment.getMemberScope())); 575 } 576 577 for (DeclarationDescriptor declaration : sort(members)) { 578 if (skip != null && skip.invoke(declaration)) continue; 579 580 if (declaration instanceof PropertyDescriptor) { 581 builder.addProperty(propertyProto((PropertyDescriptor) declaration)); 582 } 583 else if (declaration instanceof FunctionDescriptor) { 584 builder.addFunction(functionProto((FunctionDescriptor) declaration)); 585 } 586 } 587 588 ProtoBuf.TypeTable typeTableProto = typeTable.serialize(); 589 if (typeTableProto != null) { 590 builder.setTypeTable(typeTableProto); 591 } 592 593 extension.serializePackage(builder); 594 595 return builder; 596 } 597 598 @NotNull 599 public ProtoBuf.Package.Builder packagePartProto(@NotNull Collection<DeclarationDescriptor> members) { 600 ProtoBuf.Package.Builder builder = ProtoBuf.Package.newBuilder(); 601 602 for (DeclarationDescriptor declaration : sort(members)) { 603 if (declaration instanceof PropertyDescriptor) { 604 builder.addProperty(propertyProto((PropertyDescriptor) declaration)); 605 } 606 else if (declaration instanceof FunctionDescriptor) { 607 builder.addFunction(functionProto((FunctionDescriptor) declaration)); 608 } 609 } 610 611 ProtoBuf.TypeTable typeTableProto = typeTable.serialize(); 612 if (typeTableProto != null) { 613 builder.setTypeTable(typeTableProto); 614 } 615 616 extension.serializePackage(builder); 617 618 return builder; 619 } 620 621 @NotNull 622 private static ProtoBuf.Type.Argument.Projection projection(@NotNull Variance projectionKind) { 623 switch (projectionKind) { 624 case INVARIANT: 625 return ProtoBuf.Type.Argument.Projection.INV; 626 case IN_VARIANCE: 627 return ProtoBuf.Type.Argument.Projection.IN; 628 case OUT_VARIANCE: 629 return ProtoBuf.Type.Argument.Projection.OUT; 630 } 631 throw new IllegalStateException("Unknown projectionKind: " + projectionKind); 632 } 633 634 private int getClassId(@NotNull ClassDescriptor descriptor) { 635 return getStringTable().getFqNameIndex(descriptor); 636 } 637 638 private int getSimpleNameIndex(@NotNull Name name) { 639 return getStringTable().getStringIndex(name.asString()); 640 } 641 642 private int getTypeParameterId(@NotNull TypeParameterDescriptor descriptor) { 643 return typeParameters.intern(descriptor); 644 } 645 646 private static boolean hasAnnotations(Annotated descriptor) { 647 return !descriptor.getAnnotations().isEmpty(); 648 } 649 650 @NotNull 651 public static <T extends DeclarationDescriptor> List<T> sort(@NotNull Collection<T> descriptors) { 652 List<T> result = new ArrayList<T>(descriptors); 653 //NOTE: the exact comparator does matter here 654 Collections.sort(result, MemberComparator.INSTANCE); 655 return result; 656 657 } 658 }