From 96db81983220352bcd5cc879797e58b56260d093 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 14 May 2013 14:35:11 +0400 Subject: [PATCH] Extracted IndexedSymbolTable and TypeDeserializer --- .../serialization/DescriptorDeserializer.java | 117 ++-------------- .../serialization/IndexedSymbolTable.java | 45 ++++++ .../serialization/TypeDeserializer.java | 132 ++++++++++++++++++ 3 files changed, 186 insertions(+), 108 deletions(-) create mode 100644 compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/IndexedSymbolTable.java create mode 100644 compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java 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 d92a95dabf5..b44075733f4 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 @@ -16,7 +16,6 @@ package org.jetbrains.jet.descriptors.serialization; -import gnu.trove.TIntObjectHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -36,18 +35,17 @@ import java.util.Collections; import java.util.List; public class DescriptorDeserializer { - @Nullable - private final DescriptorDeserializer parent; private final DeclarationDescriptor containingDeclaration; private final NameResolver nameResolver; - private final TIntObjectHashMap typeParameterDescriptors = new TIntObjectHashMap(); + private final TypeDeserializer typeDeserializer; public DescriptorDeserializer( @Nullable DescriptorDeserializer parent, @NotNull DeclarationDescriptor containingDeclaration, @NotNull NameResolver nameResolver ) { - this.parent = parent; + TypeDeserializer parentTypeDeserializer = parent == null ? null : parent.typeDeserializer; + this.typeDeserializer = new TypeDeserializer(parentTypeDeserializer, nameResolver); this.containingDeclaration = containingDeclaration; this.nameResolver = nameResolver; } @@ -57,19 +55,6 @@ public class DescriptorDeserializer { return new DescriptorDeserializer(this, descriptor, nameResolver); } - private void registerTypeParameter(int id, @NotNull TypeParameterDescriptorImpl descriptor) { - typeParameterDescriptors.put(id, descriptor); - } - - @Nullable - private TypeParameterDescriptorImpl getTypeParameter(int id) { - TypeParameterDescriptorImpl descriptor = typeParameterDescriptors.get(id); - if (descriptor == null && parent != null) { - return parent.getTypeParameter(id); - } - return descriptor; - } - @NotNull public ClassDescriptor loadClass(@NotNull ProtoBuf.Class proto) { MutableClassDescriptor descriptor = new MutableClassDescriptor( @@ -110,7 +95,7 @@ public class DescriptorDeserializer { List supertypes = new ArrayList(proto.getSupertypesCount()); for (ProtoBuf.Type supertype : proto.getSupertypesList()) { - supertypes.add(local.type(supertype)); + supertypes.add(local.typeDeserializer.type(supertype)); } descriptor.setSupertypes(supertypes); @@ -133,12 +118,12 @@ public class DescriptorDeserializer { ); DescriptorDeserializer local = new DescriptorDeserializer(this, function, nameResolver); function.initialize( - local.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null), + local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null), // TODO: expectedThisObject null, local.typeParameters(proto.getTypeParametersList()), local.valueParameters(proto.getValueParametersList()), - local.type(proto.getReturnType()), + local.typeDeserializer.type(proto.getReturnType()), // TODO: modality Modality.OPEN, // TODO: visibility @@ -150,90 +135,6 @@ public class DescriptorDeserializer { return function; } - @Nullable - private JetType typeOrNull(@Nullable ProtoBuf.Type proto) { - if (proto == null) { - return null; - } - return type(proto); - } - - @NotNull - private JetType type(@NotNull 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.getFqName(id).getFqName() - : "Unknown type parameter " + id; - return ErrorUtils.createErrorType(message); - } - - List typeArguments = typeArguments(proto.getArgumentsList()); - return new JetTypeImpl( - Collections.emptyList(), - typeConstructor, - proto.getNullable(), - typeArguments, - getTypeMemberScope(typeConstructor, typeArguments) - ); - } - - @NotNull - private static JetScope getTypeMemberScope(@NotNull TypeConstructor constructor, @NotNull List typeArguments) { - ClassifierDescriptor descriptor = constructor.getDeclarationDescriptor(); - if (descriptor instanceof TypeParameterDescriptor) { - TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor; - return typeParameterDescriptor.getDefaultType().getMemberScope(); - } - return ((ClassDescriptor) descriptor).getMemberScope(typeArguments); - } - - @Nullable - private TypeConstructor typeConstructor(@NotNull ProtoBuf.Type.Constructor proto) { - switch (proto.getKind()) { - case CLASS: - ClassDescriptor classDescriptor = nameResolver.getClassDescriptor(proto.getId()); - if (classDescriptor == null) return null; - - return classDescriptor.getTypeConstructor(); - case TYPE_PARAMETER: - TypeParameterDescriptorImpl descriptor = getTypeParameter(proto.getId()); - if (descriptor == null) return null; - - return descriptor.getTypeConstructor(); - } - throw new IllegalStateException("Unknown kind " + proto.getKind()); - } - - private List typeArguments(List protos) { - List result = new ArrayList(protos.size()); - for (ProtoBuf.Type.Argument proto : protos) { - result.add(typeProjection(proto)); - } - return result; - } - - private TypeProjection typeProjection(ProtoBuf.Type.Argument proto) { - return new TypeProjection( - 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 List typeParameters(@NotNull List protos) { List result = new ArrayList(protos.size()); @@ -255,7 +156,7 @@ public class DescriptorDeserializer { variance(proto.getVariance()), nameResolver.getName(proto.getName()), index); - registerTypeParameter(id, descriptor); + typeDeserializer.registerTypeParameter(id, descriptor); // TODO: circular bounds descriptor.setInitialized(); return descriptor; @@ -290,9 +191,9 @@ public class DescriptorDeserializer { // TODO Collections.emptyList(), nameResolver.getName(proto.getName()), - type(proto.getType()), + typeDeserializer.type(proto.getType()), // TODO: declaresDefaultValue false, - typeOrNull(proto.hasVarargElementType() ? proto.getVarargElementType() : null)); + typeDeserializer.typeOrNull(proto.hasVarargElementType() ? proto.getVarargElementType() : null)); } } diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/IndexedSymbolTable.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/IndexedSymbolTable.java new file mode 100644 index 00000000000..3bb137303fd --- /dev/null +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/IndexedSymbolTable.java @@ -0,0 +1,45 @@ +/* + * 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 org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class IndexedSymbolTable { + @Nullable + private final IndexedSymbolTable parent; + private final TIntObjectHashMap symbols = new TIntObjectHashMap(); + + public IndexedSymbolTable(@Nullable IndexedSymbolTable parent) { + this.parent = parent; + } + + public void registerSymbol(int id, @NotNull T symbol) { + symbols.put(id, symbol); + } + + @Nullable + public T getSymbol(int id) { + T symbol = symbols.get(id); + if (symbol == null && parent != null) { + return parent.getSymbol(id); + } + return symbol; + } + +} diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java new file mode 100644 index 00000000000..463ff542627 --- /dev/null +++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/TypeDeserializer.java @@ -0,0 +1,132 @@ +/* + * 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.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.types.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class TypeDeserializer { + private final NameResolver nameResolver; + private final IndexedSymbolTable typeParameterDescriptors; + + public TypeDeserializer( + @Nullable TypeDeserializer parent, + @NotNull NameResolver nameResolver + ) { + IndexedSymbolTable parentTypeParameters = parent == null ? null : parent.typeParameterDescriptors; + this.typeParameterDescriptors = new IndexedSymbolTable(parentTypeParameters); + this.nameResolver = nameResolver; + } + + public void registerTypeParameter(int id, TypeParameterDescriptor typeParameter) { + typeParameterDescriptors.registerSymbol(id, typeParameter); + } + + @Nullable + public JetType typeOrNull(@Nullable ProtoBuf.Type proto) { + if (proto == null) { + return null; + } + return type(proto); + } + + @NotNull + public JetType type(@NotNull 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.getFqName(id).asString() + : "Unknown type parameter " + id; + return ErrorUtils.createErrorType(message); + } + + List typeArguments = typeArguments(proto.getArgumentsList()); + return new JetTypeImpl( + Collections.emptyList(), + typeConstructor, + proto.getNullable(), + typeArguments, + getTypeMemberScope(typeConstructor, typeArguments) + ); + } + + @Nullable + private TypeConstructor typeConstructor(@NotNull ProtoBuf.Type.Constructor proto) { + switch (proto.getKind()) { + case CLASS: + ClassDescriptor classDescriptor = nameResolver.getClassDescriptor(proto.getId()); + if (classDescriptor == null) return null; + + return classDescriptor.getTypeConstructor(); + case TYPE_PARAMETER: + TypeParameterDescriptor descriptor = typeParameterDescriptors.getSymbol(proto.getId()); + if (descriptor == null) return null; + + return descriptor.getTypeConstructor(); + } + throw new IllegalStateException("Unknown kind " + proto.getKind()); + } + + private List typeArguments(List protos) { + List result = new ArrayList(protos.size()); + for (ProtoBuf.Type.Argument proto : protos) { + result.add(typeProjection(proto)); + } + return result; + } + + private TypeProjection typeProjection(ProtoBuf.Type.Argument proto) { + return new TypeProjection( + 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 typeArguments) { + ClassifierDescriptor descriptor = constructor.getDeclarationDescriptor(); + if (descriptor instanceof TypeParameterDescriptor) { + TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) descriptor; + return typeParameterDescriptor.getDefaultType().getMemberScope(); + } + return ((ClassDescriptor) descriptor).getMemberScope(typeArguments); + } +}