Move module 'serialization' to core/

This commit is contained in:
Alexander Udalov
2014-04-29 21:32:08 +04:00
parent 16daeb9544
commit b7746cbee7
34 changed files with 140 additions and 125 deletions
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="protobuf-java" level="project" />
<orderEntry type="library" name="trove4j" level="project" />
<orderEntry type="module" module-name="util.runtime" exported="" />
<orderEntry type="module" module-name="descriptors" exported="" />
</component>
</module>
+228
View File
@@ -0,0 +1,228 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
option java_outer_classname = "ProtoBuf";
option optimize_for = LITE_RUNTIME; // Smaller runtime
option java_generic_services = false; // Less code
message SimpleNameTable {
repeated string name = 1;
}
message QualifiedNameTable {
message QualifiedName {
optional int32 parent_qualified_name = 1 [default = -1];
required int32 short_name = 2;
optional Kind kind = 3 [default = PACKAGE];
enum Kind {
CLASS = 0;
PACKAGE = 1;
}
}
repeated QualifiedName qualified_name = 1;
}
message Type {
message Constructor {
enum Kind {
CLASS = 0;
TYPE_PARAMETER = 1;
}
optional Kind kind = 1 [default = CLASS];
required int32 id = 2; // CLASS - fqName id, TYPE_PARAMETER - type parameter id
}
required Constructor constructor = 1;
message Argument {
enum Projection {
IN = 0;
OUT = 1;
INV = 2;
}
optional Projection projection = 1 [default = INV];
required Type type = 2;
}
repeated Argument argument = 2;
optional bool nullable = 3 [default = false];
}
message TypeParameter {
required int32 id = 1;
required int32 name = 2;
optional bool reified = 3 [default = false];
enum Variance {
IN = 0;
OUT = 1;
INV = 2;
}
optional Variance variance = 4 [default = INV];
repeated Type upper_bound = 5;
}
message Class {
enum Kind {
// 3 bits
CLASS = 0;
TRAIT = 1;
ENUM_CLASS = 2;
ENUM_ENTRY = 3;
ANNOTATION_CLASS = 4;
OBJECT = 5;
CLASS_OBJECT = 6;
}
/*
Visibility
Modality
has_annotation
ClassKind
is_inner
*/
optional int32 flags = 1 [default = 0 /*internal final class, no annotations*/];
optional string extra_visibility = 2; // for things like java-specific visibilities
required int32 fq_name = 3;
message ClassObject {
// If this field is present, it contains serialized data for a synthetic class object, for which there's no class file.
// Otherwise class object was compiled to a separate class file and serialized data can be found in the annotation on that class
optional Class data = 1;
}
// This field is present if and only if the class has a class object. Its proto should be found either here or in the separate file
optional ClassObject class_object = 4;
repeated TypeParameter type_parameter = 5;
repeated Type supertype = 6;
// we store only names, because the actual information must reside in the corresponding .class files,
// to be obtainable through reflection at runtime
repeated int32 nested_class_name = 7;
repeated Callable member = 11;
repeated int32 enum_entry = 12;
message PrimaryConstructor {
// If this field is present, it contains serialized data for the primary constructor.
// Otherwise it's default and can be created manually upon deserialization
optional Callable data = 1;
}
// This field is present if and only if the class has a primary constructor
optional PrimaryConstructor primary_constructor = 13;
// todo: other constructors?
}
message Package {
repeated Callable member = 1;
}
message Callable {
enum MemberKind {
// 2 bits
DECLARATION = 0;
FAKE_OVERRIDE = 1;
DELEGATION = 2;
SYNTHESIZED = 3;
}
enum CallableKind {
// 2 bits
FUN = 0;
VAL = 1;
VAR = 2;
CONSTRUCTOR = 3;
}
/*
Visibility
Modality
has_annotations
CallableKind
MemberKind
hasGetter
hasSetter
hasConstant
*/
optional int32 flags = 1;
optional string extra_visibility = 2; // for things like java-specific visibilities
/*
isNotDefault
Visibility
Modality
has_annotations
*/
optional int32 getter_flags = 9 /* absent => same as property */;
optional int32 setter_flags = 10 /* absent => same as property */;
repeated TypeParameter type_parameter = 4;
optional Type receiver_type = 5;
required int32 name = 6;
message ValueParameter {
/*
declaresDefault
has_annotations
*/
optional int32 flags = 1;
required int32 name = 2;
required Type type = 3;
optional Type vararg_element_type = 4;
extensions 100 to 199;
}
// Value parameters for functions and constructors, or setter value parameter for properties
repeated ValueParameter value_parameter = 7;
required Type return_type = 8;
extensions 100 to 199;
}
enum Modality {
// 2 bits
FINAL = 0x00;
OPEN = 0x01;
ABSTRACT = 0x02;
}
enum Visibility {
// 3 bits
INTERNAL = 0x00;
PRIVATE = 0x01;
PROTECTED = 0x02;
PUBLIC = 0x03;
EXTRA = 0x04; // there's an extra field for the actual visibility
}
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import kotlin.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider;
import org.jetbrains.jet.storage.MemoizedFunctionToNullable;
import org.jetbrains.jet.storage.StorageManager;
public abstract class AbstractDescriptorFinder implements DescriptorFinder {
private final MemoizedFunctionToNullable<ClassId, ClassDescriptor> findClass;
private final Deserializers deserializers;
public AbstractDescriptorFinder(
@NotNull final StorageManager storageManager,
@NotNull Deserializers deserializers,
@NotNull final PackageFragmentProvider packageFragmentProvider
) {
this.deserializers = deserializers;
this.findClass = storageManager.createMemoizedFunctionWithNullableValues(new Function1<ClassId, ClassDescriptor>() {
@Override
public ClassDescriptor invoke(ClassId classId) {
ClassData classData = getClassData(classId);
if (classData == null) {
return null;
}
AbstractDescriptorFinder _this = AbstractDescriptorFinder.this;
return new DeserializedClassDescriptor(storageManager, _this.deserializers, _this, packageFragmentProvider,
classData.getNameResolver(), classData.getClassProto());
}
});
}
@Nullable
@Override
public ClassDescriptor findClass(@NotNull ClassId classId) {
return findClass.invoke(classId);
}
@Nullable
protected abstract ClassData getClassData(@NotNull ClassId classId);
}
@@ -0,0 +1,72 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import com.google.protobuf.ExtensionRegistryLite;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.utils.UtilsPackage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public final class ClassData {
@NotNull
public static ClassData read(@NotNull byte[] bytes, @NotNull ExtensionRegistryLite registry) {
try {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
NameResolver nameResolver = NameSerializationUtil.deserializeNameResolver(in);
ProtoBuf.Class classProto = ProtoBuf.Class.parseFrom(in, registry);
return new ClassData(nameResolver, classProto);
}
catch (IOException e) {
throw UtilsPackage.rethrow(e);
}
}
private final NameResolver nameResolver;
private final ProtoBuf.Class classProto;
public ClassData(@NotNull NameResolver nameResolver, @NotNull ProtoBuf.Class classProto) {
this.nameResolver = nameResolver;
this.classProto = classProto;
}
@NotNull
public NameResolver getNameResolver() {
return nameResolver;
}
@NotNull
public ProtoBuf.Class getClassProto() {
return classProto;
}
@NotNull
public byte[] toBytes() {
try {
ByteArrayOutputStream result = new ByteArrayOutputStream();
NameSerializationUtil.serializeNameResolver(result, nameResolver);
classProto.writeTo(result);
return result.toByteArray();
}
catch (IOException e) {
throw UtilsPackage.rethrow(e);
}
}
}
@@ -0,0 +1,95 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
public final class ClassId {
@NotNull
public static ClassId topLevel(@NotNull FqName topLevelFqName) {
return new ClassId(topLevelFqName.parent(), FqNameUnsafe.topLevel(topLevelFqName.shortName()));
}
private final FqName packageFqName;
private final FqNameUnsafe relativeClassName;
public ClassId(@NotNull FqName packageFqName, @NotNull FqNameUnsafe relativeClassName) {
this.packageFqName = packageFqName;
assert !relativeClassName.isRoot() : "Class name must not be root. " + packageFqName;
this.relativeClassName = relativeClassName;
}
@NotNull
public FqName getPackageFqName() {
return packageFqName;
}
@NotNull
public FqNameUnsafe getRelativeClassName() {
return relativeClassName;
}
@NotNull
public ClassId createNestedClassId(@NotNull Name name) {
return new ClassId(getPackageFqName(), relativeClassName.child(name));
}
@NotNull
public ClassId getOuterClassId() {
return new ClassId(getPackageFqName(), relativeClassName.parent());
}
public boolean isTopLevelClass() {
return relativeClassName.parent().isRoot();
}
@NotNull
public FqNameUnsafe asSingleFqName() {
if (packageFqName.isRoot()) return relativeClassName;
return new FqNameUnsafe(packageFqName.asString() + "." + relativeClassName.asString());
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ClassId id = (ClassId) o;
if (!packageFqName.equals(id.packageFqName)) return false;
if (!relativeClassName.equals(id.relativeClassName)) return false;
return true;
}
@Override
public int hashCode() {
int result = packageFqName.hashCode();
result = 31 * result + relativeClassName.hashCode();
return result;
}
@Override
public String toString() {
if (packageFqName.isRoot()) return "/" + relativeClassName;
return packageFqName.toString().replace('.', '/') + "/" + relativeClassName;
}
}
@@ -0,0 +1,427 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import kotlin.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.descriptors.*;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.*;
import org.jetbrains.jet.lang.resolve.DescriptorFactory;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.storage.StorageManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable;
import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.TypeParameter;
import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE;
import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind;
public class DescriptorDeserializer {
@NotNull
public static DescriptorDeserializer create(
@NotNull StorageManager storageManager,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull NameResolver nameResolver,
@NotNull DescriptorFinder descriptorFinder,
@NotNull Deserializers deserializers
) {
return new DescriptorDeserializer(storageManager,
new TypeDeserializer(storageManager, null, nameResolver, descriptorFinder,
"Deserializer for " + containingDeclaration.getName(), NONE),
containingDeclaration, nameResolver, deserializers);
}
@NotNull
public static DescriptorDeserializer create(
@NotNull StorageManager storageManager,
@NotNull TypeDeserializer typeDeserializer,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull NameResolver nameResolver,
@NotNull Deserializers deserializers
) {
return new DescriptorDeserializer(storageManager, typeDeserializer, containingDeclaration, nameResolver, deserializers);
}
private final DeclarationDescriptor containingDeclaration;
private final NameResolver nameResolver;
private final TypeDeserializer typeDeserializer;
private final Deserializers deserializers;
private final StorageManager storageManager;
private DescriptorDeserializer(
@NotNull StorageManager storageManager,
@NotNull TypeDeserializer typeDeserializer,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull NameResolver nameResolver,
@NotNull Deserializers deserializers
) {
this.storageManager = storageManager;
this.typeDeserializer = typeDeserializer;
this.containingDeclaration = containingDeclaration;
this.nameResolver = nameResolver;
this.deserializers = deserializers;
}
@NotNull
public TypeDeserializer getTypeDeserializer() {
return typeDeserializer;
}
@NotNull
public NameResolver getNameResolver() {
return nameResolver;
}
@NotNull
public DescriptorDeserializer createChildDeserializer(
@NotNull DeclarationDescriptor descriptor,
@NotNull final List<TypeParameter> typeParameterProtos,
@NotNull final List<TypeParameterDescriptor> typeParameters
) {
TypeDeserializer childTypeDeserializer = new TypeDeserializer(
storageManager,
typeDeserializer, "Child deserializer for " + descriptor.getName(),
new TypeDeserializer.TypeParameterResolver() {
@NotNull
@Override
public List<DeserializedTypeParameterDescriptor> getTypeParameters(@NotNull TypeDeserializer typeDeserializer) {
List<DeserializedTypeParameterDescriptor> descriptors = typeParameters(typeParameterProtos, typeDeserializer);
typeParameters.addAll(descriptors);
return descriptors;
}
});
return create(storageManager, childTypeDeserializer, descriptor, nameResolver, deserializers);
}
@NotNull
public CallableMemberDescriptor loadCallable(@NotNull Callable proto) {
Callable.CallableKind callableKind = Flags.CALLABLE_KIND.get(proto.getFlags());
switch (callableKind) {
case FUN:
return loadFunction(proto);
case VAL:
case VAR:
return loadProperty(proto);
case CONSTRUCTOR:
return loadConstructor(proto);
}
throw new IllegalArgumentException("Unsupported callable kind: " + callableKind);
}
@NotNull
private PropertyDescriptor loadProperty(@NotNull final Callable proto) {
final int flags = proto.getFlags();
DeserializedPropertyDescriptor property = new DeserializedPropertyDescriptor(
containingDeclaration,
null,
getAnnotations(proto, flags, AnnotatedCallableKind.PROPERTY),
modality(Flags.MODALITY.get(flags)),
visibility(Flags.VISIBILITY.get(flags)),
Flags.CALLABLE_KIND.get(flags) == Callable.CallableKind.VAR,
nameResolver.getName(proto.getName()),
memberKind(Flags.MEMBER_KIND.get(flags)),
proto,
nameResolver
);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
DescriptorDeserializer local = createChildDeserializer(property, proto.getTypeParameterList(), typeParameters);
property.setType(
local.typeDeserializer.type(proto.getReturnType()),
typeParameters,
getExpectedThisObject(),
local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null)
);
PropertyGetterDescriptorImpl getter = null;
PropertySetterDescriptorImpl setter = null;
if (Flags.HAS_GETTER.get(flags)) {
int getterFlags = proto.getGetterFlags();
boolean isNotDefault = proto.hasGetterFlags() && Flags.IS_NOT_DEFAULT.get(getterFlags);
if (isNotDefault) {
getter = new PropertyGetterDescriptorImpl(property,
getAnnotations(proto, getterFlags, AnnotatedCallableKind.PROPERTY_GETTER),
modality(Flags.MODALITY.get(getterFlags)),
visibility(Flags.VISIBILITY.get(getterFlags)), isNotDefault, !isNotDefault,
property.getKind(), null);
}
else {
getter = DescriptorFactory.createDefaultGetter(property);
}
getter.initialize(property.getReturnType());
}
if (Flags.HAS_SETTER.get(flags)) {
int setterFlags = proto.getSetterFlags();
boolean isNotDefault = proto.hasSetterFlags() && Flags.IS_NOT_DEFAULT.get(setterFlags);
if (isNotDefault) {
setter = new PropertySetterDescriptorImpl(property,
getAnnotations(proto, setterFlags, AnnotatedCallableKind.PROPERTY_SETTER),
modality(Flags.MODALITY.get(setterFlags)),
visibility(Flags.VISIBILITY.get(setterFlags)), isNotDefault, !isNotDefault,
property.getKind(), null);
DescriptorDeserializer setterLocal = local.createChildDeserializer(setter, Collections.<TypeParameter>emptyList(),
Collections.<TypeParameterDescriptor>emptyList());
List<ValueParameterDescriptor> valueParameters = setterLocal.valueParameters(proto, AnnotatedCallableKind.PROPERTY_SETTER);
assert valueParameters.size() == 1 : "Property setter should have a single value parameter: " + setter;
setter.initialize(valueParameters.get(0));
}
else {
setter = DescriptorFactory.createDefaultSetter(property);
}
}
if (Flags.HAS_CONSTANT.get(flags)) {
property.setCompileTimeInitializer(
storageManager.createNullableLazyValue(new Function0<CompileTimeConstant<?>>() {
@Nullable
@Override
public CompileTimeConstant<?> invoke() {
assert containingDeclaration instanceof ClassOrPackageFragmentDescriptor
: "Only members in classes or package fragments should be serialized: " + containingDeclaration;
return deserializers.getConstantDeserializer().loadPropertyConstant(
(ClassOrPackageFragmentDescriptor) containingDeclaration,
proto, nameResolver,
AnnotatedCallableKind.PROPERTY);
}
})
);
}
property.initialize(getter, setter);
return property;
}
@NotNull
private CallableMemberDescriptor loadFunction(@NotNull Callable proto) {
int flags = proto.getFlags();
DeserializedSimpleFunctionDescriptor function = DeserializedSimpleFunctionDescriptor.create(
containingDeclaration, proto,
deserializers,
nameResolver
);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
DescriptorDeserializer local = createChildDeserializer(function, proto.getTypeParameterList(), typeParameters);
function.initialize(
local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null),
getExpectedThisObject(),
typeParameters,
local.valueParameters(proto, AnnotatedCallableKind.FUNCTION),
local.typeDeserializer.type(proto.getReturnType()),
modality(Flags.MODALITY.get(flags)),
visibility(Flags.VISIBILITY.get(flags))
);
return function;
}
@Nullable
private ReceiverParameterDescriptor getExpectedThisObject() {
return containingDeclaration instanceof ClassDescriptor
? ((ClassDescriptor) containingDeclaration).getThisAsReceiverParameter() : null;
}
@NotNull
private CallableMemberDescriptor loadConstructor(@NotNull Callable proto) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
ConstructorDescriptorImpl descriptor = ConstructorDescriptorImpl.create(
classDescriptor,
getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION),
// TODO: primary
true);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
DescriptorDeserializer local = createChildDeserializer(descriptor, Collections.<TypeParameter>emptyList(), typeParameters);
descriptor.initialize(
classDescriptor.getTypeConstructor().getParameters(),
local.valueParameters(proto, AnnotatedCallableKind.FUNCTION),
visibility(Flags.VISIBILITY.get(proto.getFlags())),
DescriptorUtils.isConstructorOfStaticNestedClass(descriptor)
);
descriptor.setReturnType(local.typeDeserializer.type(proto.getReturnType()));
return descriptor;
}
@NotNull
private Annotations getAnnotations(@NotNull Callable proto, int flags, @NotNull AnnotatedCallableKind kind) {
return getAnnotations(containingDeclaration, proto, flags, kind, deserializers.getAnnotationDeserializer(), nameResolver);
}
public static Annotations getAnnotations(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Callable proto,
int flags,
@NotNull AnnotatedCallableKind kind,
@NotNull AnnotationDeserializer annotationDeserializer,
@NotNull NameResolver nameResolver
) {
assert containingDeclaration instanceof ClassOrPackageFragmentDescriptor
: "Only members in classes or package fragments should be serialized: " + containingDeclaration;
return Flags.HAS_ANNOTATIONS.get(flags)
? annotationDeserializer
.loadCallableAnnotations((ClassOrPackageFragmentDescriptor) containingDeclaration, proto, nameResolver, kind)
: Annotations.EMPTY;
}
public static CallableMemberDescriptor.Kind memberKind(Callable.MemberKind memberKind) {
switch (memberKind) {
case DECLARATION:
return CallableMemberDescriptor.Kind.DECLARATION;
case FAKE_OVERRIDE:
return CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
case DELEGATION:
return CallableMemberDescriptor.Kind.DELEGATION;
case SYNTHESIZED:
return CallableMemberDescriptor.Kind.SYNTHESIZED;
}
throw new IllegalArgumentException("Unknown member kind: " + memberKind);
}
@NotNull
public static Modality modality(@NotNull ProtoBuf.Modality modality) {
switch (modality) {
case FINAL:
return Modality.FINAL;
case OPEN:
return Modality.OPEN;
case ABSTRACT:
return Modality.ABSTRACT;
}
throw new IllegalArgumentException("Unknown modality: " + modality);
}
@NotNull
public static Visibility visibility(@NotNull ProtoBuf.Visibility visibility) {
switch (visibility) {
case INTERNAL:
return Visibilities.INTERNAL;
case PRIVATE:
return Visibilities.PRIVATE;
case PROTECTED:
return Visibilities.PROTECTED;
case PUBLIC:
return Visibilities.PUBLIC;
case EXTRA:
throw new UnsupportedOperationException("Extra visibilities are not supported yet"); // TODO
}
throw new IllegalArgumentException("Unknown visibility: " + visibility);
}
@NotNull
public static ClassKind classKind(@NotNull ProtoBuf.Class.Kind kind) {
switch (kind) {
case CLASS:
return ClassKind.CLASS;
case TRAIT:
return ClassKind.TRAIT;
case ENUM_CLASS:
return ClassKind.ENUM_CLASS;
case ENUM_ENTRY:
return ClassKind.ENUM_ENTRY;
case ANNOTATION_CLASS:
return ClassKind.ANNOTATION_CLASS;
case OBJECT:
return ClassKind.OBJECT;
case CLASS_OBJECT:
return ClassKind.CLASS_OBJECT;
}
throw new IllegalArgumentException("Unknown class kind: " + kind);
}
@NotNull
public List<DeserializedTypeParameterDescriptor> typeParameters(
@NotNull List<TypeParameter> protos,
@NotNull TypeDeserializer typeDeserializer
) {
List<DeserializedTypeParameterDescriptor> result = new ArrayList<DeserializedTypeParameterDescriptor>(protos.size());
for (int i = 0; i < protos.size(); i++) {
TypeParameter proto = protos.get(i);
DeserializedTypeParameterDescriptor descriptor = new DeserializedTypeParameterDescriptor(
storageManager,
typeDeserializer,
proto,
containingDeclaration,
nameResolver.getName(proto.getName()),
variance(proto.getVariance()),
proto.getReified(),
i
);
result.add(descriptor);
}
return result;
}
private static Variance variance(TypeParameter.Variance proto) {
switch (proto) {
case IN:
return Variance.IN_VARIANCE;
case OUT:
return Variance.OUT_VARIANCE;
case INV:
return Variance.INVARIANT;
}
throw new IllegalStateException("Unknown projection: " + proto);
}
@NotNull
private List<ValueParameterDescriptor> valueParameters(@NotNull Callable callable, @NotNull AnnotatedCallableKind kind) {
DeclarationDescriptor containerOfCallable = containingDeclaration.getContainingDeclaration();
assert containerOfCallable instanceof ClassOrPackageFragmentDescriptor
: "Only members in classes or package fragments should be serialized: " + containerOfCallable;
ClassOrPackageFragmentDescriptor classOrPackage = (ClassOrPackageFragmentDescriptor) containerOfCallable;
List<Callable.ValueParameter> protos = callable.getValueParameterList();
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(protos.size());
for (int i = 0; i < protos.size(); i++) {
Callable.ValueParameter proto = protos.get(i);
result.add(new ValueParameterDescriptorImpl(
containingDeclaration,
null,
i,
getAnnotations(classOrPackage, callable, kind, proto),
nameResolver.getName(proto.getName()),
typeDeserializer.type(proto.getType()),
Flags.DECLARES_DEFAULT_VALUE.get(proto.getFlags()),
typeDeserializer.typeOrNull(proto.hasVarargElementType() ? proto.getVarargElementType() : null))
);
}
return result;
}
@NotNull
private Annotations getAnnotations(
@NotNull ClassOrPackageFragmentDescriptor classOrPackage,
@NotNull Callable callable,
@NotNull AnnotatedCallableKind kind,
@NotNull Callable.ValueParameter valueParameter
) {
return Flags.HAS_ANNOTATIONS.get(valueParameter.getFlags())
? deserializers.getAnnotationDeserializer().loadValueParameterAnnotations(classOrPackage, callable, nameResolver, kind, valueParameter)
: Annotations.EMPTY;
}
}
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.Collection;
import java.util.Collections;
public interface DescriptorFinder {
DescriptorFinder EMPTY = new DescriptorFinder() {
@Nullable
@Override
public ClassDescriptor findClass(@NotNull ClassId classId) {
return null;
}
@NotNull
@Override
public Collection<Name> getClassNames(@NotNull FqName packageName) {
return Collections.emptyList();
}
};
@Nullable
ClassDescriptor findClass(@NotNull ClassId classId);
@ReadOnly
@NotNull
Collection<Name> getClassNames(@NotNull FqName packageName);
}
@@ -0,0 +1,447 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.resolve.DescriptorFactory;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.renderer.DescriptorRenderer;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
public class DescriptorSerializer {
private static final DescriptorRenderer RENDERER = DescriptorRenderer.STARTS_FROM_NAME;
private static final Comparator<DeclarationDescriptor> DESCRIPTOR_COMPARATOR = new Comparator<DeclarationDescriptor>() {
@Override
public int compare(@NotNull DeclarationDescriptor o1, @NotNull DeclarationDescriptor o2) {
int names = o1.getName().compareTo(o2.getName());
if (names != 0) return names;
String o1String = RENDERER.render(o1);
String o2String = RENDERER.render(o2);
return o1String.compareTo(o2String);
}
};
private final NameTable nameTable;
private final Interner<TypeParameterDescriptor> typeParameters;
private final SerializerExtension extension;
public DescriptorSerializer() {
this(SerializerExtension.DEFAULT);
}
public DescriptorSerializer(@NotNull SerializerExtension extension) {
this(new NameTable(), new Interner<TypeParameterDescriptor>(), extension);
}
private DescriptorSerializer(NameTable nameTable, Interner<TypeParameterDescriptor> typeParameters, SerializerExtension extension) {
this.nameTable = nameTable;
this.typeParameters = typeParameters;
this.extension = extension;
}
private DescriptorSerializer createChildSerializer() {
return new DescriptorSerializer(nameTable, new Interner<TypeParameterDescriptor>(typeParameters), extension);
}
@NotNull
public NameTable getNameTable() {
return nameTable;
}
@NotNull
public ProtoBuf.Class.Builder classProto(@NotNull ClassDescriptor classDescriptor) {
ProtoBuf.Class.Builder builder = ProtoBuf.Class.newBuilder();
int flags = Flags.getClassFlags(hasAnnotations(classDescriptor), classDescriptor.getVisibility(),
classDescriptor.getModality(), classDescriptor.getKind(), classDescriptor.isInner());
builder.setFlags(flags);
// TODO extra visibility
builder.setFqName(getClassId(classDescriptor));
DescriptorSerializer local = createChildSerializer();
for (TypeParameterDescriptor typeParameterDescriptor : classDescriptor.getTypeConstructor().getParameters()) {
builder.addTypeParameter(local.typeParameter(typeParameterDescriptor));
}
if (extension.hasSupertypes(classDescriptor)) {
// Special classes (Any, Nothing) have no supertypes
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
builder.addSupertype(local.type(supertype));
}
}
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
if (primaryConstructor != null) {
if (DescriptorFactory.isDefaultPrimaryConstructor(primaryConstructor)) {
builder.setPrimaryConstructor(ProtoBuf.Class.PrimaryConstructor.getDefaultInstance());
}
else {
ProtoBuf.Class.PrimaryConstructor.Builder constructorBuilder = ProtoBuf.Class.PrimaryConstructor.newBuilder();
constructorBuilder.setData(local.callableProto(primaryConstructor));
builder.setPrimaryConstructor(constructorBuilder);
}
}
// TODO: other constructors
for (DeclarationDescriptor descriptor : sort(classDescriptor.getDefaultType().getMemberScope().getAllDescriptors())) {
if (descriptor instanceof CallableMemberDescriptor) {
CallableMemberDescriptor member = (CallableMemberDescriptor) descriptor;
if (member.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) continue;
builder.addMember(local.callableProto(member));
}
}
Collection<DeclarationDescriptor> nestedClasses = classDescriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors();
for (DeclarationDescriptor descriptor : sort(nestedClasses)) {
if (!isEnumEntry(descriptor)) {
builder.addNestedClassName(nameTable.getSimpleNameIndex(descriptor.getName()));
}
}
ClassDescriptor classObject = classDescriptor.getClassObjectDescriptor();
if (classObject != null) {
builder.setClassObject(classObjectProto(classObject));
}
if (classDescriptor.getKind() == ClassKind.ENUM_CLASS) {
// Not calling sort() here, because the order of enum entries matters
for (DeclarationDescriptor descriptor : nestedClasses) {
if (isEnumEntry(descriptor)) {
builder.addEnumEntry(nameTable.getSimpleNameIndex(descriptor.getName()));
}
}
}
return builder;
}
@NotNull
private ProtoBuf.Class.ClassObject classObjectProto(@NotNull ClassDescriptor classObject) {
if (isObject(classObject.getContainingDeclaration())) {
return ProtoBuf.Class.ClassObject.newBuilder().setData(classProto(classObject)).build();
}
return ProtoBuf.Class.ClassObject.getDefaultInstance();
}
@NotNull
public ProtoBuf.Callable.Builder callableProto(@NotNull CallableMemberDescriptor descriptor) {
ProtoBuf.Callable.Builder builder = ProtoBuf.Callable.newBuilder();
DescriptorSerializer local = createChildSerializer();
boolean hasGetter = false;
boolean hasSetter = false;
boolean hasConstant = false;
if (descriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
int propertyFlags = Flags.getAccessorFlags(
hasAnnotations(propertyDescriptor),
propertyDescriptor.getVisibility(),
propertyDescriptor.getModality(),
false
);
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
if (getter != null) {
hasGetter = true;
int accessorFlags = getAccessorFlags(getter);
if (accessorFlags != propertyFlags) {
builder.setGetterFlags(accessorFlags);
}
}
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
if (setter != null) {
hasSetter = true;
int accessorFlags = getAccessorFlags(setter);
if (accessorFlags != propertyFlags) {
builder.setSetterFlags(accessorFlags);
}
if (!setter.isDefault()) {
for (ValueParameterDescriptor valueParameterDescriptor : setter.getValueParameters()) {
builder.addValueParameter(local.valueParameter(valueParameterDescriptor));
}
}
}
hasConstant = propertyDescriptor.getCompileTimeInitializer() != null;
}
builder.setFlags(Flags.getCallableFlags(
hasAnnotations(descriptor),
descriptor.getVisibility(),
descriptor.getModality(),
descriptor.getKind(),
callableKind(descriptor),
hasGetter,
hasSetter,
hasConstant
));
//TODO builder.setExtraVisibility()
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
builder.addTypeParameter(local.typeParameter(typeParameterDescriptor));
}
ReceiverParameterDescriptor receiverParameter = descriptor.getReceiverParameter();
if (receiverParameter != null) {
builder.setReceiverType(local.type(receiverParameter.getType()));
}
builder.setName(nameTable.getSimpleNameIndex(descriptor.getName()));
for (ValueParameterDescriptor valueParameterDescriptor : descriptor.getValueParameters()) {
builder.addValueParameter(local.valueParameter(valueParameterDescriptor));
}
builder.setReturnType(local.type(getSerializableReturnType(descriptor.getReturnType())));
extension.serializeCallable(descriptor, builder, nameTable);
return builder;
}
@NotNull
private static JetType getSerializableReturnType(@NotNull JetType type) {
return isSerializableType(type) ? type : KotlinBuiltIns.getInstance().getAnyType();
}
/**
* @return true iff this type can be serialized. Types which correspond to type parameters, top-level classes, inner classes, and
* generic classes with serializable arguments are serializable. For other types (local classes, inner of local, etc.) it may be
* problematical to construct a FQ name for serialization
*/
private static boolean isSerializableType(@NotNull JetType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor instanceof TypeParameterDescriptor) {
return true;
}
else if (descriptor instanceof ClassDescriptor) {
for (TypeProjection projection : type.getArguments()) {
if (!isSerializableType(projection.getType())) {
return false;
}
}
return isTopLevelOrInnerClass((ClassDescriptor) descriptor);
}
else {
throw new IllegalStateException("Unknown type constructor: " + type);
}
}
private static int getAccessorFlags(@NotNull PropertyAccessorDescriptor accessor) {
return Flags.getAccessorFlags(
hasAnnotations(accessor),
accessor.getVisibility(),
accessor.getModality(),
!accessor.isDefault()
);
}
@NotNull
private static ProtoBuf.Callable.CallableKind callableKind(@NotNull CallableMemberDescriptor descriptor) {
if (descriptor instanceof PropertyDescriptor) {
return ((PropertyDescriptor) descriptor).isVar() ? ProtoBuf.Callable.CallableKind.VAR : ProtoBuf.Callable.CallableKind.VAL;
}
if (descriptor instanceof ConstructorDescriptor) {
return ProtoBuf.Callable.CallableKind.CONSTRUCTOR;
}
assert descriptor instanceof FunctionDescriptor : "Unknown descriptor class: " + descriptor.getClass();
return ProtoBuf.Callable.CallableKind.FUN;
}
@NotNull
private ProtoBuf.Callable.ValueParameter.Builder valueParameter(@NotNull ValueParameterDescriptor descriptor) {
ProtoBuf.Callable.ValueParameter.Builder builder = ProtoBuf.Callable.ValueParameter.newBuilder();
builder.setFlags(Flags.getValueParameterFlags(hasAnnotations(descriptor), descriptor.declaresDefaultValue()));
builder.setName(nameTable.getSimpleNameIndex(descriptor.getName()));
builder.setType(type(descriptor.getType()));
JetType varargElementType = descriptor.getVarargElementType();
if (varargElementType != null) {
builder.setVarargElementType(type(varargElementType));
}
extension.serializeValueParameter(descriptor, builder, nameTable);
return builder;
}
private ProtoBuf.TypeParameter.Builder typeParameter(TypeParameterDescriptor typeParameter) {
ProtoBuf.TypeParameter.Builder builder = ProtoBuf.TypeParameter.newBuilder();
builder.setId(getTypeParameterId(typeParameter));
builder.setName(nameTable.getSimpleNameIndex(typeParameter.getName()));
// to avoid storing a default
if (typeParameter.isReified()) {
builder.setReified(true);
}
// to avoid storing a default
ProtoBuf.TypeParameter.Variance variance = variance(typeParameter.getVariance());
if (variance != ProtoBuf.TypeParameter.Variance.INV) {
builder.setVariance(variance);
}
for (JetType upperBound : typeParameter.getUpperBounds()) {
builder.addUpperBound(type(upperBound));
}
return builder;
}
private static ProtoBuf.TypeParameter.Variance variance(Variance variance) {
switch (variance) {
case INVARIANT:
return ProtoBuf.TypeParameter.Variance.INV;
case IN_VARIANCE:
return ProtoBuf.TypeParameter.Variance.IN;
case OUT_VARIANCE:
return ProtoBuf.TypeParameter.Variance.OUT;
}
throw new IllegalStateException("Unknown variance: " + variance);
}
@NotNull
public ProtoBuf.Type.Builder type(@NotNull JetType type) {
assert !type.isError() : "Can't serialize error types: " + type; // TODO
ProtoBuf.Type.Builder builder = ProtoBuf.Type.newBuilder();
builder.setConstructor(typeConstructor(type.getConstructor()));
for (TypeProjection projection : type.getArguments()) {
builder.addArgument(typeArgument(projection));
}
// to avoid storing a default
if (type.isNullable()) {
builder.setNullable(true);
}
return builder;
}
@NotNull
private ProtoBuf.Type.Argument.Builder typeArgument(@NotNull TypeProjection typeProjection) {
ProtoBuf.Type.Argument.Builder builder = ProtoBuf.Type.Argument.newBuilder();
ProtoBuf.Type.Argument.Projection projection = projection(typeProjection.getProjectionKind());
// to avoid storing a default
if (projection != ProtoBuf.Type.Argument.Projection.INV) {
builder.setProjection(projection);
}
builder.setType(type(typeProjection.getType()));
return builder;
}
@NotNull
private ProtoBuf.Type.Constructor.Builder typeConstructor(@NotNull TypeConstructor typeConstructor) {
ProtoBuf.Type.Constructor.Builder builder = ProtoBuf.Type.Constructor.newBuilder();
ClassifierDescriptor declarationDescriptor = typeConstructor.getDeclarationDescriptor();
assert declarationDescriptor instanceof TypeParameterDescriptor || declarationDescriptor instanceof ClassDescriptor
: "Unknown declaration descriptor: " + typeConstructor;
if (declarationDescriptor instanceof TypeParameterDescriptor) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) declarationDescriptor;
builder.setKind(ProtoBuf.Type.Constructor.Kind.TYPE_PARAMETER);
builder.setId(getTypeParameterId(typeParameterDescriptor));
}
else {
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
//default: builder.setKind(Type.Constructor.Kind.CLASS);
builder.setId(getClassId(classDescriptor));
}
return builder;
}
@NotNull
public ProtoBuf.Package.Builder packageProto(@NotNull Collection<PackageFragmentDescriptor> fragments) {
ProtoBuf.Package.Builder builder = ProtoBuf.Package.newBuilder();
Collection<DeclarationDescriptor> members = new ArrayList<DeclarationDescriptor>();
for (PackageFragmentDescriptor fragment : fragments) {
members.addAll(fragment.getMemberScope().getAllDescriptors());
}
for (DeclarationDescriptor declaration : sort(members)) {
if (declaration instanceof PropertyDescriptor || declaration instanceof FunctionDescriptor) {
builder.addMember(callableProto((CallableMemberDescriptor) declaration));
}
}
return builder;
}
@NotNull
private static ProtoBuf.Type.Argument.Projection projection(@NotNull Variance projectionKind) {
switch (projectionKind) {
case INVARIANT:
return ProtoBuf.Type.Argument.Projection.INV;
case IN_VARIANCE:
return ProtoBuf.Type.Argument.Projection.IN;
case OUT_VARIANCE:
return ProtoBuf.Type.Argument.Projection.OUT;
}
throw new IllegalStateException("Unknown projectionKind: " + projectionKind);
}
private int getClassId(@NotNull ClassDescriptor descriptor) {
return nameTable.getFqNameIndex(descriptor);
}
private int getTypeParameterId(@NotNull TypeParameterDescriptor descriptor) {
return typeParameters.intern(descriptor);
}
private static boolean hasAnnotations(Annotated descriptor) {
return !descriptor.getAnnotations().isEmpty();
}
@NotNull
public static <T extends DeclarationDescriptor> List<T> sort(@NotNull Collection<T> descriptors) {
List<T> result = new ArrayList<T>(descriptors);
Collections.sort(result, DESCRIPTOR_COMPARATOR);
return result;
}
}
@@ -0,0 +1,245 @@
package org.jetbrains.jet.descriptors.serialization;
import com.google.protobuf.Internal;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
public class Flags {
private Flags() {}
// Common
public static final FlagField<Boolean> HAS_ANNOTATIONS = FlagField.booleanFirst();
public static final FlagField<ProtoBuf.Visibility> VISIBILITY = FlagField.after(HAS_ANNOTATIONS, ProtoBuf.Visibility.values());
public static final FlagField<ProtoBuf.Modality> MODALITY = FlagField.after(VISIBILITY, ProtoBuf.Modality.values());
// Class
public static final FlagField<ProtoBuf.Class.Kind> CLASS_KIND = FlagField.after(MODALITY, ProtoBuf.Class.Kind.values());
public static final FlagField<Boolean> INNER = FlagField.booleanAfter(CLASS_KIND);
// Callables
public static final FlagField<ProtoBuf.Callable.CallableKind> CALLABLE_KIND = FlagField.after(MODALITY,
ProtoBuf.Callable.CallableKind.values());
public static final FlagField<ProtoBuf.Callable.MemberKind> MEMBER_KIND = FlagField.after(CALLABLE_KIND,
ProtoBuf.Callable.MemberKind.values());
public static final FlagField<Boolean> HAS_GETTER = FlagField.booleanAfter(MEMBER_KIND);
public static final FlagField<Boolean> HAS_SETTER = FlagField.booleanAfter(HAS_GETTER);
public static final FlagField<Boolean> HAS_CONSTANT = FlagField.booleanAfter(HAS_SETTER);
// Parameters
public static final FlagField<Boolean> DECLARES_DEFAULT_VALUE = FlagField.booleanAfter(HAS_ANNOTATIONS);
// Accessors
// It's important that this flag is negated: "is NOT default" instead of "is default"
public static final FlagField<Boolean> IS_NOT_DEFAULT = FlagField.booleanAfter(MODALITY);
// ---
private static <E> int bitWidth(@NotNull E[] enumEntries) {
int length = enumEntries.length - 1;
if (length == 0) return 1;
for (int i = 31; i >= 0; i--) {
if ((length & (1 << i)) != 0) return i + 1;
}
throw new IllegalStateException("Empty enum: " + enumEntries.getClass());
}
public static int getClassFlags(
boolean hasAnnotations,
Visibility visibility,
Modality modality,
ClassKind kind,
boolean inner
) {
return HAS_ANNOTATIONS.toFlags(hasAnnotations)
| MODALITY.toFlags(modality(modality))
| VISIBILITY.toFlags(visibility(visibility))
| CLASS_KIND.toFlags(classKind(kind))
| INNER.toFlags(inner)
;
}
private static ProtoBuf.Class.Kind classKind(ClassKind kind) {
switch (kind) {
case CLASS:
return ProtoBuf.Class.Kind.CLASS;
case TRAIT:
return ProtoBuf.Class.Kind.TRAIT;
case ENUM_CLASS:
return ProtoBuf.Class.Kind.ENUM_CLASS;
case ENUM_ENTRY:
return ProtoBuf.Class.Kind.ENUM_ENTRY;
case ANNOTATION_CLASS:
return ProtoBuf.Class.Kind.ANNOTATION_CLASS;
case OBJECT:
return ProtoBuf.Class.Kind.OBJECT;
case CLASS_OBJECT:
return ProtoBuf.Class.Kind.CLASS_OBJECT;
}
throw new IllegalArgumentException("Unknown class kind: " + kind);
}
public static int getCallableFlags(
boolean hasAnnotations,
@NotNull Visibility visibility,
@NotNull Modality modality,
@NotNull CallableMemberDescriptor.Kind memberKind,
@NotNull ProtoBuf.Callable.CallableKind callableKind,
boolean hasGetter,
boolean hasSetter,
boolean hasConstant
) {
return HAS_ANNOTATIONS.toFlags(hasAnnotations)
| MODALITY.toFlags(modality(modality))
| VISIBILITY.toFlags(visibility(visibility))
| MEMBER_KIND.toFlags(memberKind(memberKind))
| CALLABLE_KIND.toFlags(callableKind)
| HAS_GETTER.toFlags(hasGetter)
| HAS_SETTER.toFlags(hasSetter)
| HAS_CONSTANT.toFlags(hasConstant)
;
}
public static int getAccessorFlags(
boolean hasAnnotations,
@NotNull Visibility visibility,
@NotNull Modality modality,
boolean isNotDefault
) {
return HAS_ANNOTATIONS.toFlags(hasAnnotations)
| MODALITY.toFlags(modality(modality))
| VISIBILITY.toFlags(visibility(visibility))
| IS_NOT_DEFAULT.toFlags(isNotDefault)
;
}
@NotNull
private static ProtoBuf.Visibility visibility(@NotNull Visibility visibility) {
if (visibility == Visibilities.INTERNAL) {
return ProtoBuf.Visibility.INTERNAL;
}
else if (visibility == Visibilities.PUBLIC) {
return ProtoBuf.Visibility.PUBLIC;
}
else if (visibility == Visibilities.PRIVATE) {
return ProtoBuf.Visibility.PRIVATE;
}
else if (visibility == Visibilities.PROTECTED) {
return ProtoBuf.Visibility.PROTECTED;
}
return ProtoBuf.Visibility.EXTRA;
}
@NotNull
private static ProtoBuf.Modality modality(@NotNull Modality modality) {
switch (modality) {
case FINAL:
return ProtoBuf.Modality.FINAL;
case OPEN:
return ProtoBuf.Modality.OPEN;
case ABSTRACT:
return ProtoBuf.Modality.ABSTRACT;
}
throw new IllegalArgumentException("Unknown modality: " + modality);
}
@NotNull
private static ProtoBuf.Callable.MemberKind memberKind(@NotNull CallableMemberDescriptor.Kind kind) {
switch (kind) {
case DECLARATION:
return ProtoBuf.Callable.MemberKind.DECLARATION;
case FAKE_OVERRIDE:
return ProtoBuf.Callable.MemberKind.FAKE_OVERRIDE;
case DELEGATION:
return ProtoBuf.Callable.MemberKind.DELEGATION;
case SYNTHESIZED:
return ProtoBuf.Callable.MemberKind.SYNTHESIZED;
}
throw new IllegalArgumentException("Unknown member kind: " + kind);
}
public static int getValueParameterFlags(boolean hasAnnotations, boolean declaresDefaultValue) {
return HAS_ANNOTATIONS.toFlags(hasAnnotations)
| DECLARES_DEFAULT_VALUE.toFlags(declaresDefaultValue)
;
}
// Infrastructure
public static abstract class FlagField<E> {
public static <E extends Internal.EnumLite> FlagField<E> after(FlagField<?> previousField, E[] values) {
int offset = previousField.offset + previousField.bitWidth;
return new EnumLiteFlagField<E>(offset, values);
}
public static <E extends Internal.EnumLite> FlagField<E> first(E[] values) {
return new EnumLiteFlagField<E>(0, values);
}
public static FlagField<Boolean> booleanFirst() {
return new BooleanFlagField(0);
}
public static FlagField<Boolean> booleanAfter(FlagField<?> previousField) {
int offset = previousField.offset + previousField.bitWidth;
return new BooleanFlagField(offset);
}
private final int offset;
private final int bitWidth;
private final E[] values;
private FlagField(int offset, E[] values) {
this.offset = offset;
this.bitWidth = bitWidth(values);
this.values = values;
}
public E get(int flags) {
int maskUnshifted = (1 << bitWidth) - 1;
int mask = maskUnshifted << offset;
int value = (flags & mask) >> offset;
return values[value];
}
public int toFlags(E value) {
return getIntValue(value) << offset;
}
protected abstract int getIntValue(E value);
}
private static class BooleanFlagField extends FlagField<Boolean> {
private static final Boolean[] BOOLEAN = { false, true };
public BooleanFlagField(int offset) {
super(offset, BOOLEAN);
}
@Override
protected int getIntValue(Boolean value) {
return value ? 1 : 0;
}
}
private static class EnumLiteFlagField<E extends Internal.EnumLite> extends FlagField<E> {
public EnumLiteFlagField(int offset, E[] values) {
super(offset, values);
}
@Override
protected int getIntValue(E value) {
return value.getNumber();
}
}
}
@@ -0,0 +1,70 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import gnu.trove.TObjectHashingStrategy;
import gnu.trove.TObjectIntHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
public final class Interner<T> {
private final Interner<T> parent;
private final int firstIndex;
private final TObjectIntHashMap<T> interned;
private final List<T> all = new ArrayList<T>();
public Interner(Interner<T> parent, @NotNull TObjectHashingStrategy<T> hashing) {
this.parent = parent;
this.firstIndex = parent == null ? 0 : parent.all.size();
this.interned = new TObjectIntHashMap<T>(hashing);
}
public Interner(@NotNull TObjectHashingStrategy<T> hashing) {
this(null, hashing);
}
public Interner(@Nullable Interner<T> parent) {
//noinspection unchecked
this(parent, TObjectHashingStrategy.CANONICAL);
}
public Interner() {
//noinspection unchecked
this((Interner) null);
}
public int intern(@NotNull T obj) {
assert parent == null || parent.all.size() == firstIndex : "Parent changed in parallel with child: indexes will be wrong";
if (parent != null && parent.interned.contains(obj)) {
return parent.intern(obj);
}
if (interned.contains(obj)) {
return interned.get(obj);
}
int index = firstIndex + interned.size();
interned.put(obj, index);
all.add(obj);
return index;
}
public List<T> getAllInternedObjects() {
return all;
}
}
@@ -0,0 +1,104 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.QualifiedNameTable.QualifiedName;
public class NameResolver {
private final ProtoBuf.SimpleNameTable simpleNames;
private final ProtoBuf.QualifiedNameTable qualifiedNames;
public NameResolver(
@NotNull ProtoBuf.SimpleNameTable simpleNames,
@NotNull ProtoBuf.QualifiedNameTable qualifiedNames
) {
this.simpleNames = simpleNames;
this.qualifiedNames = qualifiedNames;
}
@NotNull
public ProtoBuf.SimpleNameTable getSimpleNameTable() {
return simpleNames;
}
@NotNull
public ProtoBuf.QualifiedNameTable getQualifiedNameTable() {
return qualifiedNames;
}
@NotNull
public Name getName(int index) {
String name = simpleNames.getName(index);
return Name.guess(name);
}
@NotNull
public ClassId getClassId(int index) {
QualifiedName fqNameProto = qualifiedNames.getQualifiedName(index);
assert fqNameProto.getKind() == ProtoBuf.QualifiedNameTable.QualifiedName.Kind.CLASS : "Not a class fqName: " + fqNameProto.getKind();
StringBuilder relativeClassName = new StringBuilder();
QualifiedName packageFqNameProto = renderFqName(relativeClassName, fqNameProto, QualifiedName.Kind.CLASS);
FqName packageFqName;
if (packageFqNameProto != null) {
StringBuilder sb = new StringBuilder();
QualifiedName mustBeNull = renderFqName(sb, packageFqNameProto, QualifiedName.Kind.PACKAGE);
assert mustBeNull == null : "Prefix of an fqName must be all of kind PACKAGE";
packageFqName = new FqName(sb.toString());
}
else {
packageFqName = FqName.ROOT;
}
return new ClassId(packageFqName, new FqNameUnsafe(relativeClassName.toString()));
}
@Nullable
private QualifiedName renderFqName(StringBuilder sb, QualifiedName fqNameProto, QualifiedName.Kind kind) {
QualifiedName result = null;
if (fqNameProto.hasParentQualifiedName()) {
QualifiedName parentProto = qualifiedNames.getQualifiedName(fqNameProto.getParentQualifiedName());
if (kind == null || parentProto.getKind() == kind) {
result = renderFqName(sb, parentProto, kind);
sb.append(".");
}
else {
result = parentProto;
}
}
sb.append(simpleNames.getName(fqNameProto.getShortName()));
return result;
}
@NotNull
public FqName getFqName(int index) {
QualifiedName qualifiedName = qualifiedNames.getQualifiedName(index);
Name shortName = getName(qualifiedName.getShortName());
if (!qualifiedName.hasParentQualifiedName()) {
return FqName.topLevel(shortName);
}
return getFqName(qualifiedName.getParentQualifiedName()).child(shortName);
}
}
@@ -0,0 +1,86 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.utils.UtilsPackage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class NameSerializationUtil {
private NameSerializationUtil() {
}
@NotNull
public static NameResolver deserializeNameResolver(@NotNull InputStream in) {
try {
ProtoBuf.SimpleNameTable simpleNames = ProtoBuf.SimpleNameTable.parseDelimitedFrom(in);
ProtoBuf.QualifiedNameTable qualifiedNames = ProtoBuf.QualifiedNameTable.parseDelimitedFrom(in);
return new NameResolver(simpleNames, qualifiedNames);
}
catch (IOException e) {
throw UtilsPackage.rethrow(e);
}
}
public static void serializeNameResolver(@NotNull OutputStream out, @NotNull NameResolver nameResolver) {
serializeNameTable(out, nameResolver.getSimpleNameTable(), nameResolver.getQualifiedNameTable());
}
public static void serializeNameTable(@NotNull OutputStream out, @NotNull NameTable nameTable) {
serializeNameTable(out, toSimpleNameTable(nameTable), toQualifiedNameTable(nameTable));
}
private static void serializeNameTable(
@NotNull OutputStream out,
@NotNull ProtoBuf.SimpleNameTable simpleNameTable,
@NotNull ProtoBuf.QualifiedNameTable qualifiedNameTable
) {
try {
simpleNameTable.writeDelimitedTo(out);
qualifiedNameTable.writeDelimitedTo(out);
}
catch (IOException e) {
throw UtilsPackage.rethrow(e);
}
}
@NotNull
public static ProtoBuf.SimpleNameTable toSimpleNameTable(@NotNull NameTable nameTable) {
ProtoBuf.SimpleNameTable.Builder simpleNames = ProtoBuf.SimpleNameTable.newBuilder();
for (String simpleName : nameTable.getSimpleNames()) {
simpleNames.addName(simpleName);
}
return simpleNames.build();
}
@NotNull
public static ProtoBuf.QualifiedNameTable toQualifiedNameTable(@NotNull NameTable nameTable) {
ProtoBuf.QualifiedNameTable.Builder qualifiedNames = ProtoBuf.QualifiedNameTable.newBuilder();
for (ProtoBuf.QualifiedNameTable.QualifiedName.Builder qName : nameTable.getFqNames()) {
qualifiedNames.addQualifiedName(qName);
}
return qualifiedNames.build();
}
@NotNull
public static NameResolver createNameResolver(@NotNull NameTable table) {
return new NameResolver(toSimpleNameTable(table), toQualifiedNameTable(table));
}
}
@@ -0,0 +1,106 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.List;
import static org.jetbrains.jet.descriptors.serialization.ProtoBuf.QualifiedNameTable.QualifiedName;
public class NameTable {
public static final TObjectHashingStrategy<QualifiedName.Builder> QUALIFIED_NAME_BUILDER_HASHING =
new TObjectHashingStrategy<ProtoBuf.QualifiedNameTable.QualifiedName.Builder>() {
@Override
public int computeHashCode(QualifiedName.Builder object) {
int result = 13;
result = 31 * result + object.getParentQualifiedName();
result = 31 * result + object.getShortName();
result = 31 * result + object.getKind().hashCode();
return result;
}
@Override
public boolean equals(QualifiedName.Builder o1, QualifiedName.Builder o2) {
return o1.getParentQualifiedName() == o2.getParentQualifiedName()
&& o1.getShortName() == o2.getShortName()
&& o1.getKind() == o2.getKind();
}
};
private final Interner<String> simpleNames = new Interner<String>();
private final Interner<QualifiedName.Builder> qualifiedNames = new Interner<QualifiedName.Builder>(QUALIFIED_NAME_BUILDER_HASHING);
public NameTable() {
}
@NotNull
public List<String> getSimpleNames() {
return simpleNames.getAllInternedObjects();
}
@NotNull
public List<QualifiedName.Builder> getFqNames() {
return qualifiedNames.getAllInternedObjects();
}
public int getSimpleNameIndex(@NotNull Name name) {
return simpleNames.intern(name.asString());
}
public int getFqNameIndex(@NotNull ClassOrPackageFragmentDescriptor descriptor) {
QualifiedName.Builder builder = QualifiedName.newBuilder();
if (descriptor instanceof ClassDescriptor) {
builder.setKind(QualifiedName.Kind.CLASS);
}
builder.setShortName(getSimpleNameIndex(descriptor.getName()));
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof PackageFragmentDescriptor) {
PackageFragmentDescriptor fragment = (PackageFragmentDescriptor) containingDeclaration;
if (!fragment.getFqName().isRoot()) {
builder.setParentQualifiedName(getFqNameIndex(fragment.getFqName()));
}
}
else if (containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor outerClass = (ClassDescriptor) containingDeclaration;
builder.setParentQualifiedName(getFqNameIndex(outerClass));
}
else {
throw new IllegalStateException("FQ names are only stored for top-level or inner classes: " + descriptor);
}
return qualifiedNames.intern(builder);
}
public int getFqNameIndex(@NotNull FqName fqName) {
int result = -1;
for (Name segment : fqName.pathSegments()) {
QualifiedName.Builder builder = QualifiedName.newBuilder();
builder.setShortName(getSimpleNameIndex(segment));
if (result != -1) {
builder.setParentQualifiedName(result);
}
result = qualifiedNames.intern(builder);
}
return result;
}
}
@@ -0,0 +1,72 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import com.google.protobuf.ExtensionRegistryLite;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.utils.UtilsPackage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public final class PackageData {
@NotNull
public static PackageData read(@NotNull byte[] bytes, @NotNull ExtensionRegistryLite registry) {
try {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
NameResolver nameResolver = NameSerializationUtil.deserializeNameResolver(in);
ProtoBuf.Package packageProto = ProtoBuf.Package.parseFrom(in, registry);
return new PackageData(nameResolver, packageProto);
}
catch (IOException e) {
throw UtilsPackage.rethrow(e);
}
}
private final NameResolver nameResolver;
private final ProtoBuf.Package packageProto;
public PackageData(@NotNull NameResolver nameResolver, @NotNull ProtoBuf.Package packageProto) {
this.nameResolver = nameResolver;
this.packageProto = packageProto;
}
@NotNull
public NameResolver getNameResolver() {
return nameResolver;
}
@NotNull
public ProtoBuf.Package getPackageProto() {
return packageProto;
}
@NotNull
public byte[] toBytes() {
try {
ByteArrayOutputStream result = new ByteArrayOutputStream();
NameSerializationUtil.serializeNameResolver(result, nameResolver);
packageProto.writeTo(result);
return result.toByteArray();
}
catch (IOException e) {
throw UtilsPackage.rethrow(e);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
public abstract class SerializerExtension {
public static final SerializerExtension DEFAULT = new SerializerExtension() {};
public boolean hasSupertypes(@NotNull ClassDescriptor descriptor) {
return true;
}
public void serializeCallable(
@NotNull CallableMemberDescriptor callable,
@NotNull ProtoBuf.Callable.Builder proto,
@NotNull NameTable nameTable
) {
}
public void serializeValueParameter(
@NotNull ValueParameterDescriptor descriptor,
@NotNull ProtoBuf.Callable.ValueParameter.Builder proto,
@NotNull NameTable nameTable
) {
}
}
@@ -0,0 +1,277 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization;
import gnu.trove.TIntObjectHashMap;
import kotlin.Function0;
import kotlin.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedTypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.storage.MemoizedFunctionToNullable;
import org.jetbrains.jet.storage.NotNullLazyValue;
import org.jetbrains.jet.storage.StorageManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TypeDeserializer {
public interface TypeParameterResolver {
TypeParameterResolver NONE = new TypeParameterResolver() {
@NotNull
@Override
public List<DeserializedTypeParameterDescriptor> getTypeParameters(@NotNull TypeDeserializer typeDeserializer) {
return Collections.emptyList();
}
};
@NotNull
List<DeserializedTypeParameterDescriptor> getTypeParameters(@NotNull TypeDeserializer typeDeserializer);
}
private final NameResolver nameResolver;
private final DescriptorFinder descriptorFinder;
private final TypeDeserializer parent;
// never written to after constructor returns
private final TIntObjectHashMap<TypeParameterDescriptor> typeParameterDescriptors = new TIntObjectHashMap<TypeParameterDescriptor>();
private final MemoizedFunctionToNullable<Integer, ClassDescriptor> classDescriptors;
private final String debugName;
private final StorageManager storageManager;
public TypeDeserializer(
@NotNull StorageManager storageManager,
@NotNull TypeDeserializer parent,
@NotNull String debugName,
@NotNull TypeParameterResolver typeParameterResolver
) {
this(storageManager, parent, parent.nameResolver, parent.descriptorFinder, debugName, typeParameterResolver);
}
public TypeDeserializer(
@NotNull StorageManager storageManager,
@Nullable TypeDeserializer parent,
@NotNull NameResolver nameResolver,
@NotNull DescriptorFinder descriptorFinder,
@NotNull String debugName,
@NotNull TypeParameterResolver typeParameterResolver
) {
this.storageManager = storageManager;
this.parent = parent;
this.nameResolver = nameResolver;
this.descriptorFinder = descriptorFinder;
this.debugName = debugName + (parent == null ? "" : ". Child of " + parent.debugName);
for (DeserializedTypeParameterDescriptor typeParameterDescriptor : typeParameterResolver.getTypeParameters(this)) {
typeParameterDescriptors.put(typeParameterDescriptor.getProtoId(), typeParameterDescriptor);
}
this.classDescriptors = storageManager.createMemoizedFunctionWithNullableValues(new Function1<Integer, ClassDescriptor>() {
@Override
public ClassDescriptor invoke(Integer fqNameIndex) {
return computeClassDescriptor(fqNameIndex);
}
});
}
/* package */ DescriptorFinder getDescriptorFinder() {
return descriptorFinder;
}
@Nullable
public JetType typeOrNull(@Nullable ProtoBuf.Type proto) {
if (proto == null) {
return null;
}
return type(proto);
}
@NotNull
public JetType type(@NotNull ProtoBuf.Type proto) {
return new DeserializedType(proto);
}
private TypeConstructor typeConstructor(ProtoBuf.Type proto) {
ProtoBuf.Type.Constructor constructorProto = proto.getConstructor();
int id = constructorProto.getId();
TypeConstructor typeConstructor = typeConstructor(constructorProto);
if (typeConstructor == null) {
String message = constructorProto.getKind() == ProtoBuf.Type.Constructor.Kind.CLASS
? nameResolver.getClassId(id).asSingleFqName().asString()
: "Unknown type parameter " + id;
typeConstructor = ErrorUtils.createErrorType(message).getConstructor();
}
return typeConstructor;
}
@Nullable
private TypeConstructor typeConstructor(@NotNull ProtoBuf.Type.Constructor proto) {
switch (proto.getKind()) {
case CLASS:
ClassDescriptor classDescriptor = classDescriptors.invoke(proto.getId());
if (classDescriptor == null) return null;
return classDescriptor.getTypeConstructor();
case TYPE_PARAMETER:
return typeParameterTypeConstructor(proto);
}
throw new IllegalStateException("Unknown kind " + proto.getKind());
}
@Nullable
private TypeConstructor typeParameterTypeConstructor(@NotNull ProtoBuf.Type.Constructor proto) {
TypeParameterDescriptor descriptor = typeParameterDescriptors.get(proto.getId());
if (descriptor != null) {
return descriptor.getTypeConstructor();
}
if (parent != null) {
return parent.typeParameterTypeConstructor(proto);
}
return null;
}
@Nullable
private ClassDescriptor computeClassDescriptor(int fqNameIndex) {
ClassId classId = nameResolver.getClassId(fqNameIndex);
return descriptorFinder.findClass(classId);
}
private List<TypeProjection> typeArguments(List<ProtoBuf.Type.Argument> protos) {
List<TypeProjection> result = new ArrayList<TypeProjection>(protos.size());
for (ProtoBuf.Type.Argument proto : protos) {
result.add(typeProjection(proto));
}
return result;
}
private TypeProjection typeProjection(ProtoBuf.Type.Argument proto) {
return new TypeProjectionImpl(
variance(proto.getProjection()),
type(proto.getType())
);
}
private static Variance variance(ProtoBuf.Type.Argument.Projection proto) {
switch (proto) {
case IN:
return Variance.IN_VARIANCE;
case OUT:
return Variance.OUT_VARIANCE;
case INV:
return Variance.INVARIANT;
}
throw new IllegalStateException("Unknown projection: " + proto);
}
@NotNull
private static JetScope getTypeMemberScope(@NotNull TypeConstructor constructor, @NotNull List<TypeProjection> typeArguments) {
ClassifierDescriptor descriptor = constructor.getDeclarationDescriptor();
if (descriptor instanceof TypeParameterDescriptor) {
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor;
return typeParameterDescriptor.getDefaultType().getMemberScope();
}
return ((ClassDescriptor) descriptor).getMemberScope(typeArguments);
}
@Override
public String toString() {
return debugName;
}
private class DeserializedType extends AbstractJetType implements LazyType {
private final ProtoBuf.Type typeProto;
private final NotNullLazyValue<TypeConstructor> constructor;
private final List<TypeProjection> arguments;
private final NotNullLazyValue<JetScope> memberScope;
public DeserializedType(@NotNull ProtoBuf.Type proto) {
this.typeProto = proto;
this.arguments = typeArguments(proto.getArgumentList());
this.constructor = storageManager.createLazyValue(new Function0<TypeConstructor>() {
@Override
public TypeConstructor invoke() {
return typeConstructor(typeProto);
}
});
this.memberScope = storageManager.createLazyValue(new Function0<JetScope>() {
@Override
public JetScope invoke() {
return computeMemberScope();
}
});
}
@NotNull
@Override
public TypeConstructor getConstructor() {
return constructor.invoke();
}
@NotNull
@Override
public List<TypeProjection> getArguments() {
return arguments;
}
@Override
public boolean isNullable() {
return typeProto.getNullable();
}
@NotNull
private JetScope computeMemberScope() {
if (isError()) {
return ErrorUtils.createErrorScope(getConstructor().toString());
}
else {
return getTypeMemberScope(getConstructor(), getArguments());
}
}
@NotNull
@Override
public JetScope getMemberScope() {
return memberScope.invoke();
}
@Override
public boolean isError() {
ClassifierDescriptor descriptor = getConstructor().getDeclarationDescriptor();
return descriptor != null && ErrorUtils.isError(descriptor);
}
@NotNull
@Override
public Annotations getAnnotations() {
return Annotations.EMPTY;
}
}
}
@@ -0,0 +1,84 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.descriptors.serialization.NameResolver;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrPackageFragmentDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind;
public interface AnnotationDeserializer {
AnnotationDeserializer UNSUPPORTED = new AnnotationDeserializer() {
@NotNull
@Override
public Annotations loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto) {
return notSupported();
}
@NotNull
@Override
public Annotations loadCallableAnnotations(
@NotNull ClassOrPackageFragmentDescriptor container,
@NotNull ProtoBuf.Callable proto,
@NotNull NameResolver nameResolver,
@NotNull AnnotatedCallableKind kind
) {
return notSupported();
}
@NotNull
@Override
public Annotations loadValueParameterAnnotations(
@NotNull ClassOrPackageFragmentDescriptor container,
@NotNull ProtoBuf.Callable callable,
@NotNull NameResolver nameResolver,
@NotNull AnnotatedCallableKind kind,
@NotNull ProtoBuf.Callable.ValueParameter proto
) {
return notSupported();
}
@NotNull
private Annotations notSupported() {
throw new UnsupportedOperationException("Annotations are not supported");
}
};
@NotNull
Annotations loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto);
@NotNull
Annotations loadCallableAnnotations(
@NotNull ClassOrPackageFragmentDescriptor container,
@NotNull ProtoBuf.Callable proto,
@NotNull NameResolver nameResolver,
@NotNull AnnotatedCallableKind kind
);
@NotNull
Annotations loadValueParameterAnnotations(
@NotNull ClassOrPackageFragmentDescriptor container,
@NotNull ProtoBuf.Callable callable,
@NotNull NameResolver nameResolver,
@NotNull AnnotatedCallableKind kind,
@NotNull ProtoBuf.Callable.ValueParameter proto
);
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.NameResolver;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.lang.descriptors.ClassOrPackageFragmentDescriptor;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind;
public interface ConstantDeserializer {
ConstantDeserializer UNSUPPORTED = new ConstantDeserializer() {
@Nullable
@Override
public CompileTimeConstant<?> loadPropertyConstant(
@NotNull ClassOrPackageFragmentDescriptor container,
@NotNull ProtoBuf.Callable proto,
@NotNull NameResolver nameResolver,
@NotNull AnnotatedCallableKind kind
) {
throw new UnsupportedOperationException("Constants are not supported");
}
};
@Nullable
CompileTimeConstant<?> loadPropertyConstant(
@NotNull ClassOrPackageFragmentDescriptor container,
@NotNull ProtoBuf.Callable proto,
@NotNull NameResolver nameResolver,
@NotNull AnnotatedCallableKind kind
);
}
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors
import org.jetbrains.jet.descriptors.serialization.ProtoBuf
import org.jetbrains.jet.descriptors.serialization.NameResolver
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
public trait DeserializedCallableMemberDescriptor: CallableMemberDescriptor {
public val proto: ProtoBuf.Callable
public val nameResolver: NameResolver
}
@@ -0,0 +1,584 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors;
import kotlin.Function0;
import kotlin.Function1;
import kotlin.KotlinPackage;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.*;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.AbstractClassDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.EnumEntrySyntheticClassDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.resolve.DescriptorFactory;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.storage.MemoizedFunctionToNullable;
import org.jetbrains.jet.storage.NotNullLazyValue;
import org.jetbrains.jet.storage.NullableLazyValue;
import org.jetbrains.jet.storage.StorageManager;
import java.util.*;
import static org.jetbrains.jet.descriptors.serialization.TypeDeserializer.TypeParameterResolver.NONE;
import static org.jetbrains.jet.lang.resolve.name.SpecialNames.getClassObjectName;
public class DeserializedClassDescriptor extends AbstractClassDescriptor implements ClassDescriptor {
private final ClassId classId;
private final ProtoBuf.Class classProto;
private final StorageManager storageManager;
private final TypeDeserializer typeDeserializer;
private final DescriptorDeserializer deserializer;
private final DeserializedMemberScope memberScope;
private final NullableLazyValue<ConstructorDescriptor> primaryConstructor;
private final Deserializers deserializers;
private final NotNullLazyValue<Annotations> annotations;
private final NullableLazyValue<ClassDescriptor> classObjectDescriptor;
private final NestedClassDescriptors nestedClasses;
private final NotNullLazyValue<DeclarationDescriptor> containingDeclaration;
private final DeserializedClassTypeConstructor typeConstructor;
private final Modality modality;
private final Visibility visibility;
private final ClassKind kind;
private final boolean isInner;
private final DescriptorFinder descriptorFinder;
private final PackageFragmentProvider packageFragmentProvider;
public DeserializedClassDescriptor(
@NotNull StorageManager storageManager,
@NotNull Deserializers deserializers,
@NotNull DescriptorFinder descriptorFinder,
@NotNull PackageFragmentProvider packageFragmentProvider,
@NotNull NameResolver nameResolver,
@NotNull ProtoBuf.Class classProto
) {
super(storageManager, nameResolver.getClassId(classProto.getFqName()).getRelativeClassName().shortName());
this.classProto = classProto;
this.classId = nameResolver.getClassId(classProto.getFqName());
this.storageManager = storageManager;
this.packageFragmentProvider = packageFragmentProvider;
this.descriptorFinder = descriptorFinder;
TypeDeserializer notNullTypeDeserializer = new TypeDeserializer(storageManager, null, nameResolver,
descriptorFinder, "Deserializer for class " + getName(), NONE);
DescriptorDeserializer outerDeserializer = DescriptorDeserializer.create(storageManager, notNullTypeDeserializer,
this, nameResolver, deserializers);
List<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(classProto.getTypeParameterCount());
this.deserializer = outerDeserializer.createChildDeserializer(this, classProto.getTypeParameterList(), typeParameters);
this.typeDeserializer = deserializer.getTypeDeserializer();
this.containingDeclaration = storageManager.createLazyValue(new Function0<DeclarationDescriptor>() {
@Override
public DeclarationDescriptor invoke() {
return computeContainingDeclaration();
}
});
this.typeConstructor = new DeserializedClassTypeConstructor(typeParameters);
this.memberScope = new DeserializedClassMemberScope(storageManager, this);
int flags = classProto.getFlags();
this.modality = DescriptorDeserializer.modality(Flags.MODALITY.get(flags));
this.visibility = DescriptorDeserializer.visibility(Flags.VISIBILITY.get(flags));
this.kind = DescriptorDeserializer.classKind(Flags.CLASS_KIND.get(flags));
this.isInner = Flags.INNER.get(flags);
this.deserializers = deserializers;
this.annotations = storageManager.createLazyValue(new Function0<Annotations>() {
@Override
public Annotations invoke() {
return computeAnnotations();
}
});
this.primaryConstructor = storageManager.createNullableLazyValue(new Function0<ConstructorDescriptor>() {
@Override
public ConstructorDescriptor invoke() {
return computePrimaryConstructor();
}
});
this.classObjectDescriptor = storageManager.createNullableLazyValue(new Function0<ClassDescriptor>() {
@Override
public ClassDescriptor invoke() {
return computeClassObjectDescriptor();
}
});
this.nestedClasses = new NestedClassDescriptors();
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return containingDeclaration.invoke();
}
@NotNull
private DeclarationDescriptor computeContainingDeclaration() {
if (classId.isTopLevelClass()) {
List<PackageFragmentDescriptor> fragments = packageFragmentProvider.getPackageFragments(classId.getPackageFqName());
assert fragments.size() == 1 : "there should be exactly one package: " + fragments;
return fragments.iterator().next();
}
else {
ClassOrPackageFragmentDescriptor result = descriptorFinder.findClass(classId.getOuterClassId());
return result != null ? result : ErrorUtils.getErrorModule();
}
}
@NotNull
@Override
public TypeConstructor getTypeConstructor() {
return typeConstructor;
}
@NotNull
@Override
public ClassKind getKind() {
return kind;
}
@NotNull
@Override
public Modality getModality() {
return modality;
}
@NotNull
@Override
public Visibility getVisibility() {
return visibility;
}
@Override
public boolean isInner() {
return isInner;
}
private Annotations computeAnnotations() {
if (!Flags.HAS_ANNOTATIONS.get(classProto.getFlags())) {
return Annotations.EMPTY;
}
return deserializers.getAnnotationDeserializer().loadClassAnnotations(this, classProto);
}
@NotNull
@Override
public Annotations getAnnotations() {
return annotations.invoke();
}
@NotNull
@Override
protected JetScope getScopeForMemberLookup() {
return memberScope;
}
@Nullable
private ConstructorDescriptor computePrimaryConstructor() {
if (!classProto.hasPrimaryConstructor()) return null;
ProtoBuf.Class.PrimaryConstructor constructorProto = classProto.getPrimaryConstructor();
if (!constructorProto.hasData()) {
ConstructorDescriptorImpl descriptor = DescriptorFactory.createPrimaryConstructorForObject(this);
descriptor.setReturnType(getDefaultType());
return descriptor;
}
return (ConstructorDescriptor) deserializer.loadCallable(constructorProto.getData());
}
@Nullable
@Override
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
return primaryConstructor.invoke();
}
@NotNull
@Override
public Collection<ConstructorDescriptor> getConstructors() {
ConstructorDescriptor constructor = getUnsubstitutedPrimaryConstructor();
if (constructor == null) {
return Collections.emptyList();
}
// TODO: other constructors
return Collections.singletonList(constructor);
}
@Nullable
private ClassDescriptor computeClassObjectDescriptor() {
if (!classProto.hasClassObject()) {
return null;
}
if (getKind() == ClassKind.ENUM_CLASS) {
return createEnumClassObject();
}
if (getKind() == ClassKind.OBJECT) {
ProtoBuf.Class.ClassObject classObjectProto = classProto.getClassObject();
if (!classObjectProto.hasData()) {
throw new IllegalStateException("Object should have a serialized class object: " + classId);
}
return new DeserializedClassDescriptor(storageManager, deserializers, descriptorFinder, packageFragmentProvider,
deserializer.getNameResolver(), classObjectProto.getData());
}
return descriptorFinder.findClass(classId.createNestedClassId(getClassObjectName(getName())));
}
@NotNull
private ClassDescriptorWithResolutionScopes createEnumClassObject() {
final MutableClassDescriptor classObject = new MutableClassDescriptor(this, getScopeForMemberLookup(), ClassKind.CLASS_OBJECT,
false, getClassObjectName(getName()));
JetType supertype = KotlinBuiltIns.getInstance().getAnyType();
classObject.setSupertypes(Collections.singleton(supertype));
classObject.setModality(Modality.FINAL);
classObject.setVisibility(DescriptorUtils.getSyntheticClassObjectVisibility());
classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
classObject.setPrimaryConstructor(DescriptorFactory.createPrimaryConstructorForObject(classObject));
classObject.createTypeConstructor();
JetType enumType = getDefaultType();
JetType enumArrayType = KotlinBuiltIns.getInstance().getArrayType(enumType);
classObject.getBuilder().addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValuesMethod(classObject, enumArrayType));
classObject.getBuilder().addFunctionDescriptor(DescriptorFactory.createEnumClassObjectValueOfMethod(classObject, enumType));
OverridingUtil.DescriptorSink sink = new OverridingUtil.DescriptorSink() {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new Function1<CallableMemberDescriptor, Unit>() {
@Override
public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
throw new IllegalStateException("Cannot infer visibility for " + descriptor + " in " + classObject);
}
});
classObject.getBuilder().addFunctionDescriptor((SimpleFunctionDescriptor) fakeOverride);
}
@Override
public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
throw new IllegalStateException("Conflict on enum class object override: " + fromSuper + " vs " + fromCurrent);
}
};
JetScope superScope = supertype.getMemberScope();
for (DeclarationDescriptor descriptor : superScope.getAllDescriptors()) {
if (descriptor instanceof FunctionDescriptor) {
Name name = descriptor.getName();
OverridingUtil.generateOverridesInFunctionGroup(name, superScope.getFunctions(name),
Collections.<FunctionDescriptor>emptySet(), classObject, sink);
}
}
return classObject;
}
@Nullable
@Override
public ClassDescriptor getClassObjectDescriptor() {
return classObjectDescriptor.invoke();
}
private Collection<JetType> computeSuperTypes() {
List<JetType> supertypes = new ArrayList<JetType>(classProto.getSupertypeCount());
for (ProtoBuf.Type supertype : classProto.getSupertypeList()) {
supertypes.add(typeDeserializer.type(supertype));
}
return supertypes;
}
@Override
public String toString() {
// not using descriptor render to preserve laziness
return "deserialized class " + getName().toString();
}
private class DeserializedClassTypeConstructor implements TypeConstructor {
private final Collection<JetType> supertypes = computeSuperTypes();
private final List<TypeParameterDescriptor> parameters;
public DeserializedClassTypeConstructor(@NotNull List<TypeParameterDescriptor> typeParameters) {
parameters = typeParameters;
}
@NotNull
@Override
public List<TypeParameterDescriptor> getParameters() {
return parameters;
}
@NotNull
@Override
public Collection<JetType> getSupertypes() {
// We cannot have error supertypes because subclasses inherit error functions from them
// Filtering right away means copying the list every time, so we check for the rare condition first, and only then filter
for (JetType supertype : supertypes) {
if (supertype.isError()) {
return KotlinPackage.filter(supertypes, new Function1<JetType, Boolean>() {
@Override
public Boolean invoke(JetType type) {
return !type.isError();
}
});
}
}
return supertypes;
}
@Override
public boolean isFinal() {
return !getModality().isOverridable();
}
@Override
public boolean isDenotable() {
return true;
}
@Nullable
@Override
public ClassifierDescriptor getDeclarationDescriptor() {
return DeserializedClassDescriptor.this;
}
@NotNull
@Override
public Annotations getAnnotations() {
return Annotations.EMPTY; // TODO
}
@Override
public String toString() {
return getName().toString();
}
}
private static class DeserializedClassMemberScope extends DeserializedMemberScope {
private final DeserializedClassDescriptor classDescriptor;
public DeserializedClassMemberScope(@NotNull StorageManager storageManager, @NotNull DeserializedClassDescriptor classDescriptor) {
super(storageManager, classDescriptor, classDescriptor.deserializer, classDescriptor.classProto.getMemberList());
this.classDescriptor = classDescriptor;
}
@Override
protected void computeNonDeclaredFunctions(
@NotNull Name name, @NotNull Collection<FunctionDescriptor> functions
) {
Collection<FunctionDescriptor> fromSupertypes = new ArrayList<FunctionDescriptor>();
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name));
}
generateFakeOverrides(name, fromSupertypes, functions);
}
@Override
protected void computeNonDeclaredProperties(
@NotNull Name name, @NotNull Collection<PropertyDescriptor> property
) {
Collection<PropertyDescriptor> fromSupertypes = new ArrayList<PropertyDescriptor>();
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
//noinspection unchecked
fromSupertypes.addAll((Collection) supertype.getMemberScope().getProperties(name));
}
generateFakeOverrides(name, fromSupertypes, property);
}
private <D extends CallableMemberDescriptor> void generateFakeOverrides(
@NotNull Name name,
@NotNull Collection<D> fromSupertypes,
@NotNull final Collection<D> result
) {
List<CallableMemberDescriptor> fromCurrent = new ArrayList<CallableMemberDescriptor>(result);
OverridingUtil.generateOverridesInFunctionGroup(
name,
fromSupertypes,
fromCurrent,
classDescriptor,
new OverridingUtil.DescriptorSink() {
@Override
public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) {
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, new Function1<CallableMemberDescriptor, Unit>() {
@Override
public Unit invoke(@NotNull CallableMemberDescriptor descriptor) {
// Do nothing
// TODO: do something
return Unit.VALUE;
}
});
//noinspection unchecked
result.add((D) fakeOverride);
}
@Override
public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
// TODO report conflicts
}
}
);
}
@Override
protected void addNonDeclaredDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
if (descriptor instanceof FunctionDescriptor) {
result.addAll(getFunctions(descriptor.getName()));
}
else if (descriptor instanceof PropertyDescriptor) {
result.addAll(getProperties(descriptor.getName()));
}
// Nothing else is inherited
}
}
}
@Nullable
@Override
protected ReceiverParameterDescriptor getImplicitReceiver() {
return classDescriptor.getThisAsReceiverParameter();
}
@Nullable
@Override
protected ClassifierDescriptor getClassDescriptor(@NotNull Name name) {
return classDescriptor.nestedClasses.findClass.invoke(name);
}
@Override
protected void addAllClassDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
result.addAll(classDescriptor.nestedClasses.getAllDescriptors());
}
}
private class NestedClassDescriptors {
private final Set<Name> nestedClassNames;
private final MemoizedFunctionToNullable<Name, ClassDescriptor> findClass;
private final Set<Name> enumEntryNames;
public NestedClassDescriptors() {
this.nestedClassNames = nestedClassNames();
this.enumEntryNames = enumEntryNames();
final NotNullLazyValue<Collection<Name>> enumMemberNames = storageManager.createLazyValue(new Function0<Collection<Name>>() {
@Override
public Collection<Name> invoke() {
return computeEnumMemberNames();
}
});
this.findClass = storageManager.createMemoizedFunctionWithNullableValues(new Function1<Name, ClassDescriptor>() {
@Override
public ClassDescriptor invoke(Name name) {
if (enumEntryNames.contains(name)) {
return EnumEntrySyntheticClassDescriptor
.create(storageManager, DeserializedClassDescriptor.this, name, enumMemberNames);
}
if (nestedClassNames.contains(name)) {
return descriptorFinder.findClass(classId.createNestedClassId(name));
}
return null;
}
});
}
@NotNull
private Set<Name> nestedClassNames() {
Set<Name> result = new HashSet<Name>();
NameResolver nameResolver = deserializer.getNameResolver();
for (Integer index : classProto.getNestedClassNameList()) {
result.add(nameResolver.getName(index));
}
return result;
}
@NotNull
private Set<Name> enumEntryNames() {
if (getKind() != ClassKind.ENUM_CLASS) {
return Collections.emptySet();
}
Set<Name> result = new HashSet<Name>();
NameResolver nameResolver = deserializer.getNameResolver();
for (Integer index : classProto.getEnumEntryList()) {
result.add(nameResolver.getName(index));
}
return result;
}
@NotNull
private Collection<Name> computeEnumMemberNames() {
Collection<Name> result = new HashSet<Name>();
for (JetType supertype : getTypeConstructor().getSupertypes()) {
for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
if (descriptor instanceof SimpleFunctionDescriptor || descriptor instanceof PropertyDescriptor) {
result.add(descriptor.getName());
}
}
}
final NameResolver nameResolver = deserializer.getNameResolver();
return KotlinPackage.mapTo(classProto.getMemberList(), result, new Function1<ProtoBuf.Callable, Name>() {
@Override
public Name invoke(@NotNull ProtoBuf.Callable callable) {
return nameResolver.getName(callable.getName());
}
});
}
@NotNull
public Collection<ClassDescriptor> getAllDescriptors() {
Collection<ClassDescriptor> result = new ArrayList<ClassDescriptor>(nestedClassNames.size() + enumEntryNames.size());
for (Name name : nestedClassNames) {
ClassDescriptor descriptor = findClass.invoke(name);
if (descriptor != null) {
result.add(descriptor);
}
}
for (Name name : enumEntryNames) {
ClassDescriptor descriptor = findClass.invoke(name);
if (descriptor != null) {
result.add(descriptor);
}
}
return result;
}
}
}
@@ -0,0 +1,248 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors;
import kotlin.Function0;
import kotlin.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.DescriptorDeserializer;
import org.jetbrains.jet.descriptors.serialization.Flags;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.name.LabelName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.storage.MemoizedFunctionToNotNull;
import org.jetbrains.jet.storage.NotNullLazyValue;
import org.jetbrains.jet.storage.StorageManager;
import org.jetbrains.jet.utils.Printer;
import java.util.*;
public abstract class DeserializedMemberScope implements JetScope {
private static final Filter<ProtoBuf.Callable.CallableKind> FUNCTION = new Filter<ProtoBuf.Callable.CallableKind>() {
@Override
public boolean accept(ProtoBuf.Callable.CallableKind value) {
return value == ProtoBuf.Callable.CallableKind.FUN;
}
};
private static final Filter<ProtoBuf.Callable.CallableKind> PROPERTY = new Filter<ProtoBuf.Callable.CallableKind>() {
@Override
public boolean accept(ProtoBuf.Callable.CallableKind value) {
return value == ProtoBuf.Callable.CallableKind.VAL ||
value == ProtoBuf.Callable.CallableKind.VAR;
}
};
private final DeclarationDescriptor containingDeclaration;
private final DescriptorDeserializer deserializer;
// Never modified after creation
private final Map<Name, List<ProtoBuf.Callable>> membersProtos;
private final MemoizedFunctionToNotNull<Name, Collection<FunctionDescriptor>> functions;
private final MemoizedFunctionToNotNull<Name, Collection<VariableDescriptor>> properties;
private final NotNullLazyValue<Collection<DeclarationDescriptor>> allDescriptors;
protected DeserializedMemberScope(
@NotNull StorageManager storageManager,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull DescriptorDeserializer deserializer,
@NotNull Collection<ProtoBuf.Callable> membersList
) {
this.containingDeclaration = containingDeclaration;
this.deserializer = deserializer;
this.membersProtos = groupByName(membersList);
this.functions = storageManager.createMemoizedFunction(new Function1<Name, Collection<FunctionDescriptor>>() {
@Override
public Collection<FunctionDescriptor> invoke(Name name) {
return computeFunctions(name);
}
});
this.properties = storageManager.createMemoizedFunction(new Function1<Name, Collection<VariableDescriptor>>() {
@Override
public Collection<VariableDescriptor> invoke(Name name) {
return computeProperties(name);
}
});
this.allDescriptors = storageManager.createLazyValue(new Function0<Collection<DeclarationDescriptor>>() {
@Override
public Collection<DeclarationDescriptor> invoke() {
return computeAllDescriptors();
}
});
}
@NotNull
private Map<Name, List<ProtoBuf.Callable>> groupByName(@NotNull Collection<ProtoBuf.Callable> membersList) {
Map<Name, List<ProtoBuf.Callable>> map = new HashMap<Name, List<ProtoBuf.Callable>>();
for (ProtoBuf.Callable memberProto : membersList) {
Name name = deserializer.getNameResolver().getName(memberProto.getName());
List<ProtoBuf.Callable> protos = map.get(name);
if (protos == null) {
protos = new ArrayList<ProtoBuf.Callable>(1);
map.put(name, protos);
}
protos.add(memberProto);
}
return map;
}
@NotNull
private <D extends CallableMemberDescriptor> Collection<D> computeMembersByName(Name name, Filter<ProtoBuf.Callable.CallableKind> callableKind) {
List<ProtoBuf.Callable> memberProtos = membersProtos.get(name);
Collection<D> descriptors = new LinkedHashSet<D>(memberProtos != null ? memberProtos.size() : 0);
if (memberProtos != null) {
for (ProtoBuf.Callable memberProto : memberProtos) {
if (callableKind.accept(Flags.CALLABLE_KIND.get(memberProto.getFlags()))) {
//noinspection unchecked
descriptors.add((D) deserializer.loadCallable(memberProto));
}
}
}
return descriptors;
}
@NotNull
private Collection<FunctionDescriptor> computeFunctions(@NotNull Name name) {
Collection<FunctionDescriptor> descriptors = computeMembersByName(name, FUNCTION);
computeNonDeclaredFunctions(name, descriptors);
return descriptors;
}
protected void computeNonDeclaredFunctions(@NotNull Name name, @NotNull Collection<FunctionDescriptor> functions) {
}
@NotNull
@Override
public final Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
return functions.invoke(name);
}
@NotNull
private Collection<VariableDescriptor> computeProperties(@NotNull Name name) {
Collection<PropertyDescriptor> descriptors = computeMembersByName(name, PROPERTY);
computeNonDeclaredProperties(name, descriptors);
//noinspection unchecked
return (Collection) descriptors;
}
protected void computeNonDeclaredProperties(@NotNull Name name, @NotNull Collection<PropertyDescriptor> descriptors) {
}
@NotNull
@Override
public Collection<VariableDescriptor> getProperties(@NotNull Name name) {
return properties.invoke(name);
}
@Nullable
@Override
public final ClassifierDescriptor getClassifier(@NotNull Name name) {
return getClassDescriptor(name);
}
@Nullable
protected abstract ClassifierDescriptor getClassDescriptor(@NotNull Name name);
protected abstract void addAllClassDescriptors(@NotNull Collection<DeclarationDescriptor> result);
@Nullable
@Override
public PackageViewDescriptor getPackage(@NotNull Name name) {
return null;
}
@Nullable
@Override
public VariableDescriptor getLocalVariable(@NotNull Name name) {
return null;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return containingDeclaration;
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
return Collections.emptyList();
}
private Collection<DeclarationDescriptor> computeAllDescriptors() {
Collection<DeclarationDescriptor> result = new LinkedHashSet<DeclarationDescriptor>(0);
for (Name name : membersProtos.keySet()) {
result.addAll(getFunctions(name));
result.addAll(getProperties(name));
}
addNonDeclaredDescriptors(result);
addAllClassDescriptors(result);
return result;
}
protected abstract void addNonDeclaredDescriptors(@NotNull Collection<DeclarationDescriptor> result);
@NotNull
@Override
public final Collection<DeclarationDescriptor> getAllDescriptors() {
return allDescriptors.invoke();
}
@NotNull
@Override
public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
ReceiverParameterDescriptor receiver = getImplicitReceiver();
if (receiver != null) {
return Collections.singletonList(receiver);
}
return Collections.emptyList();
}
@Nullable
protected abstract ReceiverParameterDescriptor getImplicitReceiver();
@NotNull
@Override
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
return getAllDescriptors();
}
private interface Filter<T> {
boolean accept(T value);
}
@Override
public void printScopeStructure(@NotNull Printer p) {
p.println(getClass().getSimpleName(), " {");
p.pushIndent();
p.println("containingDeclaration = " + containingDeclaration);
p.popIndent();
p.println("}");
}
}
@@ -0,0 +1,111 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.*;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor;
import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.storage.StorageManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class DeserializedPackageMemberScope extends DeserializedMemberScope {
private final DescriptorFinder descriptorFinder;
private final FqName packageFqName;
public DeserializedPackageMemberScope(
@NotNull StorageManager storageManager,
@NotNull PackageFragmentDescriptor packageDescriptor,
@NotNull Deserializers deserializers,
@NotNull MemberFilter memberFilter,
@NotNull DescriptorFinder descriptorFinder,
@NotNull ProtoBuf.Package proto,
@NotNull NameResolver nameResolver
) {
super(storageManager, packageDescriptor,
DescriptorDeserializer.create(storageManager, packageDescriptor, nameResolver, descriptorFinder, deserializers),
getFilteredMembers(packageDescriptor, proto, memberFilter, nameResolver));
this.descriptorFinder = descriptorFinder;
this.packageFqName = packageDescriptor.getFqName();
}
public DeserializedPackageMemberScope(
@NotNull StorageManager storageManager,
@NotNull PackageFragmentDescriptor packageDescriptor,
@NotNull Deserializers deserializers,
@NotNull MemberFilter memberFilter,
@NotNull DescriptorFinder descriptorFinder,
@NotNull PackageData packageData
) {
this(storageManager, packageDescriptor, deserializers, memberFilter, descriptorFinder, packageData.getPackageProto(),
packageData.getNameResolver());
}
@Nullable
@Override
protected ClassDescriptor getClassDescriptor(@NotNull Name name) {
return descriptorFinder.findClass(new ClassId(packageFqName, FqNameUnsafe.topLevel(name)));
}
@Override
protected void addAllClassDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
for (Name className : descriptorFinder.getClassNames(packageFqName)) {
ClassDescriptor classDescriptor = getClassDescriptor(className);
if (classDescriptor != null) {
result.add(classDescriptor);
}
}
}
@Override
protected void addNonDeclaredDescriptors(@NotNull Collection<DeclarationDescriptor> result) {
// Do nothing
}
@Nullable
@Override
protected ReceiverParameterDescriptor getImplicitReceiver() {
return null;
}
@NotNull
private static Collection<ProtoBuf.Callable> getFilteredMembers(
@NotNull PackageFragmentDescriptor packageDescriptor,
@NotNull ProtoBuf.Package packageProto,
@NotNull MemberFilter memberFilter,
@NotNull NameResolver nameResolver
) {
List<ProtoBuf.Callable> result = new ArrayList<ProtoBuf.Callable>();
for (ProtoBuf.Callable member : packageProto.getMemberList()) {
if (memberFilter.acceptPackagePartClass(packageDescriptor, member, nameResolver)) {
result.add(member);
}
}
return result;
}
}
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.Modality
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.descriptors.Visibility
import org.jetbrains.jet.descriptors.serialization.NameResolver
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.jet.descriptors.serialization.ProtoBuf
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind
public class DeserializedPropertyDescriptor(
containingDeclaration: DeclarationDescriptor,
original: PropertyDescriptor?,
annotations: Annotations,
modality: Modality,
visibility: Visibility,
isVar: Boolean,
name: Name,
kind: Kind,
override public val proto: ProtoBuf.Callable,
override public val nameResolver: NameResolver
) : DeserializedCallableMemberDescriptor,
PropertyDescriptorImpl(containingDeclaration, original, annotations, modality, visibility, isVar, name, kind) {
override fun createSubstitutedCopy(
newOwner: DeclarationDescriptor,
newModality: Modality,
newVisibility: Visibility,
original: PropertyDescriptor?,
kind: Kind
): PropertyDescriptorImpl {
return DeserializedPropertyDescriptor(
newOwner, original, getAnnotations(), newModality, newVisibility, isVar(), getName(), kind, proto, nameResolver)
}
}
@@ -0,0 +1,106 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.descriptors.serialization.DescriptorDeserializer;
import org.jetbrains.jet.descriptors.serialization.Flags;
import org.jetbrains.jet.descriptors.serialization.NameResolver;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.resolve.name.Name;
public class DeserializedSimpleFunctionDescriptor extends SimpleFunctionDescriptorImpl implements DeserializedCallableMemberDescriptor {
private final ProtoBuf.Callable proto;
private final NameResolver nameResolver;
private DeserializedSimpleFunctionDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@Nullable SimpleFunctionDescriptor original,
@NotNull Annotations annotations,
@NotNull Name name,
@NotNull Kind kind,
@NotNull ProtoBuf.Callable proto,
@NotNull NameResolver nameResolver) {
super(containingDeclaration, original, annotations, name, kind);
this.proto = proto;
this.nameResolver = nameResolver;
}
@NotNull
@Override
protected FunctionDescriptorImpl createSubstitutedCopy(
@NotNull DeclarationDescriptor newOwner,
@Nullable FunctionDescriptor original,
@NotNull Kind kind
) {
return new DeserializedSimpleFunctionDescriptor(
newOwner,
(DeserializedSimpleFunctionDescriptor) original,
getAnnotations(),
getName(),
kind,
proto,
nameResolver
);
}
@NotNull
@Override
public DeserializedSimpleFunctionDescriptor getOriginal() {
return (DeserializedSimpleFunctionDescriptor) super.getOriginal();
}
@NotNull
@Override
public ProtoBuf.Callable getProto() {
return proto;
}
@NotNull
@Override
public NameResolver getNameResolver() {
return nameResolver;
}
public static DeserializedSimpleFunctionDescriptor create(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull ProtoBuf.Callable proto,
@NotNull Deserializers deserializers,
@NotNull NameResolver nameResolver
) {
Annotations annotations = DescriptorDeserializer.getAnnotations(containingDeclaration, proto, proto.getFlags(),
Deserializers.AnnotatedCallableKind.FUNCTION,
deserializers.getAnnotationDeserializer(),
nameResolver);
return new DeserializedSimpleFunctionDescriptor(
containingDeclaration,
null,
annotations,
nameResolver.getName(proto.getName()),
DescriptorDeserializer.memberKind(Flags.MEMBER_KIND.get(proto.getFlags())),
proto,
nameResolver);
}
}
@@ -0,0 +1,69 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.descriptors.serialization.TypeDeserializer;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.AbstractLazyTypeParameterDescriptor;
import org.jetbrains.jet.storage.StorageManager;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.LinkedHashSet;
import java.util.Set;
public class DeserializedTypeParameterDescriptor extends AbstractLazyTypeParameterDescriptor {
private final ProtoBuf.TypeParameter proto;
private final TypeDeserializer typeDeserializer;
public DeserializedTypeParameterDescriptor(
@NotNull StorageManager storageManager,
@NotNull TypeDeserializer typeDeserializer,
@NotNull ProtoBuf.TypeParameter proto,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Name name,
@NotNull Variance variance,
boolean isReified,
int index
) {
super(storageManager, containingDeclaration, name, variance, isReified, index);
this.proto = proto;
this.typeDeserializer = typeDeserializer;
}
@NotNull
@Override
protected Set<JetType> resolveUpperBounds() {
Set<JetType> result = new LinkedHashSet<JetType>(proto.getUpperBoundCount());
for (ProtoBuf.Type upperBound : proto.getUpperBoundList()) {
result.add(typeDeserializer.type(upperBound));
}
if (result.isEmpty()) {
result.add(KotlinBuiltIns.getInstance().getDefaultBound());
}
return result;
}
public int getProtoId() {
return proto.getId();
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors;
import org.jetbrains.annotations.NotNull;
public interface Deserializers {
Deserializers UNSUPPORTED = new Deserializers() {
@NotNull
@Override
public AnnotationDeserializer getAnnotationDeserializer() {
return AnnotationDeserializer.UNSUPPORTED;
}
@NotNull
@Override
public ConstantDeserializer getConstantDeserializer() {
return ConstantDeserializer.UNSUPPORTED;
}
};
@NotNull
AnnotationDeserializer getAnnotationDeserializer();
@NotNull
ConstantDeserializer getConstantDeserializer();
enum AnnotatedCallableKind {
FUNCTION,
PROPERTY,
PROPERTY_GETTER,
PROPERTY_SETTER
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.descriptors.serialization.descriptors
import org.jetbrains.jet.descriptors.serialization.ProtoBuf
import org.jetbrains.jet.descriptors.serialization.NameResolver
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor
public trait MemberFilter {
fun acceptPackagePartClass(container: PackageFragmentDescriptor, member: ProtoBuf.Callable, nameResolver: NameResolver): Boolean
class object {
public val ALWAYS_TRUE: MemberFilter = object : MemberFilter {
override fun acceptPackagePartClass(container: PackageFragmentDescriptor, member: ProtoBuf.Callable, nameResolver: NameResolver): Boolean = true
}
}
}