Initial implementation of (lazy) deserialized class descriptor

This commit is contained in:
Andrey Breslav
2013-05-15 13:08:15 +04:00
committed by Alexander Udalov
parent e59b4d1564
commit 915b0b79a3
4 changed files with 479 additions and 55 deletions
@@ -13,6 +13,7 @@
<orderEntry type="module" module-name="frontend" />
<orderEntry type="library" name="annotations" level="project" />
<orderEntry type="library" name="trove4j" level="project" />
<orderEntry type="library" name="intellij-core" level="project" />
</component>
</module>
@@ -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<JetType> supertypes = new ArrayList<JetType>(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
@@ -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<AnnotationDescriptor> 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<ConstructorDescriptor> 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<JetType> computeSuperTypes() {
List<JetType> supertypes = new ArrayList<JetType>(classProto.getSupertypesCount());
for (ProtoBuf.Type supertype : classProto.getSupertypesList()) {
supertypes.add(typeDeserializer.type(supertype));
}
return supertypes;
}
private class DeserializedClassTypeConstructor implements TypeConstructor {
private final Collection<JetType> supertypes = computeSuperTypes();
private final List<TypeParameterDescriptor> parameters = deserializer.typeParameters(classProto.getTypeParametersList());
@NotNull
@Override
public List<TypeParameterDescriptor> getParameters() {
return parameters;
}
@NotNull
@Override
public Collection<JetType> getSupertypes() {
return supertypes;
}
@Override
public boolean isSealed() {
return !getModality().isOverridable();
}
@Nullable
@Override
public ClassifierDescriptor getDeclarationDescriptor() {
return DeserializedClassDescriptor.this;
}
@Override
public List<AnnotationDescriptor> 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<FunctionDescriptor> getFunctions(@NotNull Name name) {
Collection<FunctionDescriptor> fromSupertypes = new ArrayList<FunctionDescriptor>();
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
fromSupertypes.addAll(supertype.getMemberScope().getFunctions(name));
}
Collection<FunctionDescriptor> result = super.getFunctions(name);
generateFakeOverrides(name, fromSupertypes, result);
return result;
}
private <D extends CallableMemberDescriptor> void generateFakeOverrides(
@NotNull Name name,
@NotNull Collection<D> fromSupertypes,
@NotNull final Collection<D> fromCurrent
) {
OverrideResolver.generateOverridesInFunctionGroup(
name,
fromSupertypes,
new ArrayList<CallableMemberDescriptor>(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<DeclarationDescriptor> result) {
// TODO inner classes
}
}
}
@@ -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<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;
public DeserializedMemberScope(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull DescriptorDeserializer deserializer,
@NotNull List<ProtoBuf.Callable> membersList
) {
this.containingDeclaration = containingDeclaration;
this.deserializer = deserializer;
this.membersProtos = groupByName(membersList);
this.functions = new MemoizedFunctionToNotNullImpl<Name, Collection<FunctionDescriptor>>() {
@NotNull
@Override
protected Collection<FunctionDescriptor> doCompute(Name name) {
return computeFunctions(name);
}
};
this.properties = new MemoizedFunctionToNotNullImpl<Name, Collection<VariableDescriptor>>() {
@NotNull
@Override
protected Collection<VariableDescriptor> doCompute(Name name) {
return computeProperties(name);
}
};
this.allDescriptors = new NotNullLazyValueImpl<Collection<DeclarationDescriptor>>() {
@NotNull
@Override
protected Collection<DeclarationDescriptor> doCompute() {
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 Collection<FunctionDescriptor> computeFunctions(@NotNull Name name) {
List<ProtoBuf.Callable> functionProtos = membersProtos.get(name);
if (functionProtos == null || functionProtos.isEmpty()) {
return Collections.emptyList();
}
List<FunctionDescriptor> functions = new ArrayList<FunctionDescriptor>(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<FunctionDescriptor> getFunctions(@NotNull Name name) {
return functions.fun(name);
}
@NotNull
private Collection<VariableDescriptor> computeProperties(@NotNull Name name) {
return Collections.emptyList(); // TODO
}
@NotNull
@Override
public Collection<VariableDescriptor> 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<DeclarationDescriptor> result);
@Nullable
@Override
public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
return null; // TODO
}
@NotNull
@Override
public Collection<ClassDescriptor> 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<DeclarationDescriptor> 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<DeclarationDescriptor> computeAllDescriptors() {
Collection<DeclarationDescriptor> result = new ArrayList<DeclarationDescriptor>();
for (Name name : membersProtos.keySet()) {
result.addAll(functions.fun(name));
result.addAll(properties.fun(name));
}
addAllClassDescriptors(result);
return result;
}
@NotNull
@Override
public final Collection<DeclarationDescriptor> getAllDescriptors() {
return allDescriptors.compute();
}
@NotNull
@Override
public List<ReceiverParameterDescriptor> getImplicitReceiversHierarchy() {
throw new UnsupportedOperationException("Should not be called");
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
return getAllDescriptors();
}
}