From 915b0b79a3183d8c3f62f6feca31363001f78ffa Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 15 May 2013 13:08:15 +0400 Subject: [PATCH] Initial implementation of (lazy) deserialized class descriptor --- .../frontend/serialization/serialization.iml | 1 + .../serialization/DescriptorDeserializer.java | 55 ---- .../DeserializedClassDescriptor.java | 270 ++++++++++++++++++ .../descriptors/DeserializedMemberScope.java | 208 ++++++++++++++ 4 files changed, 479 insertions(+), 55 deletions(-) create mode 100644 compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java create mode 100644 compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java diff --git a/compiler/frontend/serialization/serialization.iml b/compiler/frontend/serialization/serialization.iml index 0cbd573d001..b5ab6ff7b26 100644 --- a/compiler/frontend/serialization/serialization.iml +++ b/compiler/frontend/serialization/serialization.iml @@ -13,6 +13,7 @@ + diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java index 787d43608a0..fb8d149f4a6 100644 --- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java @@ -21,15 +21,9 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.Modality; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; -import org.jetbrains.jet.lang.resolve.scopes.WritableScope; -import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; -import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.Variance; import java.util.ArrayList; @@ -85,55 +79,6 @@ public class DescriptorDeserializer { return new DescriptorDeserializer(this, descriptor, nameResolver); } - @NotNull - public ClassDescriptor loadClass(@NotNull ProtoBuf.Class proto) { - MutableClassDescriptor descriptor = new MutableClassDescriptor( - containingDeclaration, - // TODO: outerScope - JetScope.EMPTY, - // TODO: kind - ClassKind.CLASS, - // TODO: isInner - false, - nameResolver.getName(proto.getName()) - ); - - - // TODO: visibility - descriptor.setVisibility(Visibilities.INTERNAL); - - // TODO: modality - descriptor.setModality(Modality.OPEN); - - DescriptorDeserializer local = createChildDeserializer(descriptor); - - descriptor.setTypeParameterDescriptors(local.typeParameters(proto.getTypeParametersList())); - - // TODO: descriptor.setPrimaryConstructor(); - - // TODO: descriptor.setAnnotations(); - - WritableScopeImpl members = new WritableScopeImpl(JetScope.EMPTY, descriptor, RedeclarationHandler.DO_NOTHING, - "Members of " + descriptor.getName()); - descriptor.setScopeForMemberLookup(members); - - for (Callable callable : proto.getMembersList()) { - // TODO: properties, classes etc - members.addFunctionDescriptor(local.loadFunction(callable)); - } - members.changeLockLevel(WritableScope.LockLevel.READING); - - List supertypes = new ArrayList(proto.getSupertypesCount()); - for (Type supertype : proto.getSupertypesList()) { - supertypes.add(local.typeDeserializer.type(supertype)); - } - descriptor.setSupertypes(supertypes); - - descriptor.createTypeConstructor(); - - return descriptor; - } - @NotNull public FunctionDescriptor loadFunction(@NotNull Callable proto) { // TODO: assert function flag diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java new file mode 100644 index 00000000000..3034573389a --- /dev/null +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedClassDescriptor.java @@ -0,0 +1,270 @@ +/* + * 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.*; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.descriptors.impl.ClassDescriptorBase; +import org.jetbrains.jet.lang.descriptors.impl.ReceiverParameterDescriptorImpl; +import org.jetbrains.jet.lang.resolve.OverrideResolver; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeConstructor; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class DeserializedClassDescriptor extends ClassDescriptorBase implements ClassDescriptor { + + private final ProtoBuf.Class classProto; + private final TypeDeserializer typeDeserializer; + private final DescriptorDeserializer deserializer; + private final DeserializedMemberScope memberScope; + private final ReceiverParameterDescriptor thisAsReceiverParameter; + + private final Name name; + private final DeclarationDescriptor containingDeclaration; + private final DeserializedClassTypeConstructor typeConstructor; + private final Modality modality; + private final Visibility visibility; + private final ClassKind kind; + private final boolean isInner; + + public DeserializedClassDescriptor( + @NotNull DeclarationDescriptor containingDeclaration, + @NotNull NameResolver nameResolver, + @NotNull ClassResolver classResolver, + @NotNull ProtoBuf.Class classProto, + @Nullable TypeDeserializer outerTypeDeserializer + ) { + this.classProto = classProto; + this.typeDeserializer = new TypeDeserializer(outerTypeDeserializer, nameResolver); + this.deserializer = new DescriptorDeserializer(typeDeserializer, this, nameResolver); + + this.containingDeclaration = containingDeclaration; + this.typeConstructor = new DeserializedClassTypeConstructor(); + this.memberScope = new DeserializedClassMemberScope(this); + this.thisAsReceiverParameter = new ReceiverParameterDescriptorImpl(this, getDefaultType(), new ClassReceiver(this)); + + this.name = nameResolver.getName(classProto.getName()); + this.modality = Modality.OPEN; // TODO + this.visibility = Visibilities.INTERNAL; // TODO + this.kind = ClassKind.CLASS; // TODO + this.isInner = false; // TODO + } + + @NotNull + @Override + public DeclarationDescriptor getOriginal() { + return this; + } + + @NotNull + @Override + public DeclarationDescriptor getContainingDeclaration() { + return containingDeclaration; + } + + @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; + } + + @NotNull + @Override + public Name getName() { + return name; + } + + @Override + public List getAnnotations() { + return Collections.emptyList(); // TODO + } + + @Override + protected JetScope getScopeForMemberLookup() { + return memberScope; + } + + @NotNull + @Override + public JetScope getUnsubstitutedInnerClassesScope() { + return JetScope.EMPTY; // TODO inner classes + } + + @Nullable + @Override + public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() { + return null; // TODO + } + + @NotNull + @Override + public Collection getConstructors() { + return Collections.emptyList(); // TODO + } + + @Nullable + @Override + public JetType getClassObjectType() { + ClassDescriptor classObjectDescriptor = getClassObjectDescriptor(); + return classObjectDescriptor == null ? null : classObjectDescriptor.getDefaultType(); + } + + @Nullable + @Override + public ClassDescriptor getClassObjectDescriptor() { + return null; // TODO + } + + @NotNull + @Override + public ReceiverParameterDescriptor getThisAsReceiverParameter() { + return thisAsReceiverParameter; + } + + private Collection computeSuperTypes() { + List supertypes = new ArrayList(classProto.getSupertypesCount()); + for (ProtoBuf.Type supertype : classProto.getSupertypesList()) { + supertypes.add(typeDeserializer.type(supertype)); + } + return supertypes; + } + + private class DeserializedClassTypeConstructor implements TypeConstructor { + private final Collection supertypes = computeSuperTypes(); + private final List parameters = deserializer.typeParameters(classProto.getTypeParametersList()); + + @NotNull + @Override + public List getParameters() { + return parameters; + } + + @NotNull + @Override + public Collection getSupertypes() { + return supertypes; + } + + @Override + public boolean isSealed() { + return !getModality().isOverridable(); + } + + @Nullable + @Override + public ClassifierDescriptor getDeclarationDescriptor() { + return DeserializedClassDescriptor.this; + } + + @Override + public List getAnnotations() { + return Collections.emptyList(); // TODO + } + } + + private static class DeserializedClassMemberScope extends DeserializedMemberScope { + private final DeserializedClassDescriptor classDescriptor; + + public DeserializedClassMemberScope(@NotNull DeserializedClassDescriptor classDescriptor) { + super(classDescriptor, classDescriptor.deserializer, classDescriptor.classProto.getMembersList()); + this.classDescriptor = classDescriptor; + } + + @NotNull + @Override + public Collection getFunctions(@NotNull Name name) { + Collection fromSupertypes = new ArrayList(); + for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) { + fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name)); + } + Collection result = super.getFunctions(name); + generateFakeOverrides(name, fromSupertypes, result); + return result; + } + + private void generateFakeOverrides( + @NotNull Name name, + @NotNull Collection fromSupertypes, + @NotNull final Collection fromCurrent + ) { + OverrideResolver.generateOverridesInFunctionGroup( + name, + fromSupertypes, + new ArrayList(fromCurrent), + classDescriptor, + new OverrideResolver.DescriptorSink() { + @Override + public void addToScope(@NotNull CallableMemberDescriptor fakeOverride) { + //noinspection unchecked + fromCurrent.add((D) fakeOverride); + } + + @Override + public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) { + // TODO report conflicts + } + } + ); + } + + @Nullable + @Override + protected ClassifierDescriptor getClassDescriptor(@NotNull Name name) { + return null; // TODO inner classes + } + + @Override + protected void addAllClassDescriptors(@NotNull Collection result) { + // TODO inner classes + } + } +} + diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java new file mode 100644 index 00000000000..d0c64c0ba7d --- /dev/null +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/DeserializedMemberScope.java @@ -0,0 +1,208 @@ +/* + * 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.ProtoBuf; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNotNull; +import org.jetbrains.jet.lang.resolve.lazy.storage.MemoizedFunctionToNotNullImpl; +import org.jetbrains.jet.lang.resolve.lazy.storage.NotNullLazyValue; +import org.jetbrains.jet.lang.resolve.lazy.storage.NotNullLazyValueImpl; +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 java.util.*; + +public abstract class DeserializedMemberScope implements JetScope { + + private final DeclarationDescriptor containingDeclaration; + private final DescriptorDeserializer deserializer; + private final Map> membersProtos; + + private final MemoizedFunctionToNotNull> functions; + private final MemoizedFunctionToNotNull> properties; + private final NotNullLazyValue> allDescriptors; + + public DeserializedMemberScope( + @NotNull DeclarationDescriptor containingDeclaration, + @NotNull DescriptorDeserializer deserializer, + @NotNull List membersList + ) { + this.containingDeclaration = containingDeclaration; + this.deserializer = deserializer; + + this.membersProtos = groupByName(membersList); + this.functions = new MemoizedFunctionToNotNullImpl>() { + @NotNull + @Override + protected Collection doCompute(Name name) { + return computeFunctions(name); + } + }; + this.properties = new MemoizedFunctionToNotNullImpl>() { + @NotNull + @Override + protected Collection doCompute(Name name) { + return computeProperties(name); + } + }; + this.allDescriptors = new NotNullLazyValueImpl>() { + @NotNull + @Override + protected Collection doCompute() { + return computeAllDescriptors(); + } + }; + } + + @NotNull + private Map> groupByName(@NotNull Collection membersList) { + Map> map = new HashMap>(); + for (ProtoBuf.Callable memberProto : membersList) { + Name name = deserializer.getNameResolver().getName(memberProto.getName()); + List protos = map.get(name); + if (protos == null) { + protos = new ArrayList(1); + map.put(name, protos); + } + protos.add(memberProto); + } + return map; + } + + @NotNull + private Collection computeFunctions(@NotNull Name name) { + List functionProtos = membersProtos.get(name); + if (functionProtos == null || functionProtos.isEmpty()) { + return Collections.emptyList(); + } + + List functions = new ArrayList(functionProtos.size()); + for (ProtoBuf.Callable memberProto : functionProtos) { + // TODO: check that the proto is a function, and not a property + functions.add(deserializer.loadFunction(memberProto)); + } + + return functions; + } + + @NotNull + @Override + public Collection getFunctions(@NotNull Name name) { + return functions.fun(name); + } + + @NotNull + private Collection computeProperties(@NotNull Name name) { + return Collections.emptyList(); // TODO + } + + @NotNull + @Override + public Collection getProperties(@NotNull Name name) { + return properties.fun(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 result); + + @Nullable + @Override + public ClassDescriptor getObjectDescriptor(@NotNull Name name) { + return null; // TODO + } + + @NotNull + @Override + public Collection getObjectDescriptors() { + return Collections.emptyList(); // TODO + } + + @Nullable + @Override + public NamespaceDescriptor getNamespace(@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 getDeclarationsByLabel(@NotNull LabelName labelName) { + throw new UnsupportedOperationException("Should not be called"); + } + + @Nullable + @Override + public PropertyDescriptor getPropertyByFieldReference(@NotNull Name fieldName) { + throw new UnsupportedOperationException("Should not be called"); + } + + private Collection computeAllDescriptors() { + Collection result = new ArrayList(); + + for (Name name : membersProtos.keySet()) { + result.addAll(functions.fun(name)); + result.addAll(properties.fun(name)); + } + + addAllClassDescriptors(result); + + return result; + } + + @NotNull + @Override + public final Collection getAllDescriptors() { + return allDescriptors.compute(); + } + + @NotNull + @Override + public List getImplicitReceiversHierarchy() { + throw new UnsupportedOperationException("Should not be called"); + } + + @NotNull + @Override + public Collection getOwnDeclaredDescriptors() { + return getAllDescriptors(); + } + +}