001 /*
002 * Copyright 2010-2013 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.jet.lang.resolve.kotlin;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.jet.descriptors.serialization.ClassId;
022 import org.jetbrains.jet.descriptors.serialization.DescriptorFinder;
023 import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil;
024 import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor;
025 import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPackageMemberScope;
026 import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
027 import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
028 import org.jetbrains.jet.lang.resolve.java.resolver.ErrorReporter;
029 import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassResolver;
030 import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver;
031 import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader;
032 import org.jetbrains.jet.lang.resolve.kotlin.header.SerializedDataHeader;
033 import org.jetbrains.jet.lang.resolve.name.FqName;
034 import org.jetbrains.jet.lang.resolve.name.Name;
035 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
036 import org.jetbrains.jet.storage.LockBasedStorageManager;
037
038 import javax.inject.Inject;
039 import java.util.Collection;
040
041 import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
042 import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
043 import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName;
044
045 public final class DeserializedDescriptorResolver {
046 private AnnotationDescriptorDeserializer annotationDeserializer;
047
048 private final LockBasedStorageManager storageManager = new LockBasedStorageManager();
049
050 private JavaNamespaceResolver javaNamespaceResolver;
051
052 private JavaClassResolver javaClassResolver;
053
054 private ErrorReporter errorReporter;
055
056 @NotNull
057 private final DescriptorFinder javaDescriptorFinder = new DescriptorFinder() {
058 @Nullable
059 @Override
060 public ClassDescriptor findClass(@NotNull ClassId classId) {
061 return javaClassResolver.resolveClass(kotlinFqNameToJavaFqName(classId.asSingleFqName()), INCLUDE_KOTLIN_SOURCES);
062 }
063
064 @Nullable
065 @Override
066 public NamespaceDescriptor findPackage(@NotNull FqName name) {
067 return javaNamespaceResolver.resolveNamespace(name, IGNORE_KOTLIN_SOURCES);
068 }
069
070 @NotNull
071 @Override
072 public Collection<Name> getClassNames(@NotNull FqName packageName) {
073 return javaNamespaceResolver.getClassNamesInPackage(packageName);
074 }
075 };
076
077 @Inject
078 public void setAnnotationDeserializer(AnnotationDescriptorDeserializer annotationDeserializer) {
079 this.annotationDeserializer = annotationDeserializer;
080 }
081
082 @Inject
083 public void setJavaNamespaceResolver(JavaNamespaceResolver javaNamespaceResolver) {
084 this.javaNamespaceResolver = javaNamespaceResolver;
085 }
086
087 @Inject
088 public void setJavaClassResolver(JavaClassResolver javaClassResolver) {
089 this.javaClassResolver = javaClassResolver;
090 }
091
092 @Inject
093 public void setErrorReporter(ErrorReporter errorReporter) {
094 this.errorReporter = errorReporter;
095 }
096
097 @Nullable
098 public ClassDescriptor resolveClass(@NotNull KotlinJvmBinaryClass kotlinClass) {
099 String[] data = readData(kotlinClass);
100 return data == null ? null : new DeserializedClassDescriptor(storageManager, annotationDeserializer, javaDescriptorFinder,
101 JavaProtoBufUtil.readClassDataFrom(data));
102 }
103
104 @Nullable
105 public JetScope createKotlinPackageScope(@NotNull NamespaceDescriptor descriptor, @NotNull KotlinJvmBinaryClass kotlinClass) {
106 String[] data = readData(kotlinClass);
107 return data == null ? null : new DeserializedPackageMemberScope(storageManager, descriptor, annotationDeserializer,
108 javaDescriptorFinder, JavaProtoBufUtil.readPackageDataFrom(data));
109 }
110
111 @Nullable
112 private String[] readData(@NotNull KotlinJvmBinaryClass kotlinClass) {
113 KotlinClassHeader header = KotlinClassHeader.read(kotlinClass);
114 if (header instanceof SerializedDataHeader) {
115 return ((SerializedDataHeader) header).getAnnotationData();
116 }
117
118 if (header != null) {
119 errorReporter.reportIncompatibleAbiVersion(kotlinClass, header.getVersion());
120 }
121
122 return null;
123 }
124 }