From 9ddbe4a414aed4b3ab0fb70e5f754c1757b630a8 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sun, 17 Jun 2012 00:27:20 +0400 Subject: [PATCH] JavaDescriptorSignatureResolver --- .../di/InjectorForJavaSemanticServices.java | 7 + .../di/InjectorForTopDownAnalyzerForJvm.java | 7 + .../resolve/java/JavaDescriptorResolver.java | 316 +-------------- .../java/JavaDescriptorSignatureResolver.java | 373 ++++++++++++++++++ 4 files changed, 401 insertions(+), 302 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorSignatureResolver.java diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaSemanticServices.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaSemanticServices.java index 133efcc21ab..e856ac82ba2 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaSemanticServices.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaSemanticServices.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.java.CompilerDependencies; import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorSignatureResolver; import org.jetbrains.jet.lang.resolve.NamespaceFactoryImpl; import org.jetbrains.jet.lang.resolve.java.CompilerDependencies; import com.intellij.openapi.project.Project; @@ -46,6 +47,7 @@ public class InjectorForJavaSemanticServices { private CompilerSpecialMode compilerSpecialMode; private final Project project; private JavaTypeTransformer javaTypeTransformer; + private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver; private NamespaceFactoryImpl namespaceFactory; public InjectorForJavaSemanticServices( @@ -62,6 +64,7 @@ public class InjectorForJavaSemanticServices { this.compilerSpecialMode = compilerDependencies.getCompilerSpecialMode(); this.project = project; this.javaTypeTransformer = new JavaTypeTransformer(); + this.javaDescriptorSignatureResolver = new JavaDescriptorSignatureResolver(); this.namespaceFactory = new NamespaceFactoryImpl(); this.javaSemanticServices.setDescriptorResolver(javaDescriptorResolver); @@ -69,6 +72,7 @@ public class InjectorForJavaSemanticServices { this.javaSemanticServices.setTrace(bindingTrace); this.javaSemanticServices.setTypeTransformer(javaTypeTransformer); + this.javaDescriptorResolver.setJavaDescriptorSignatureResolver(javaDescriptorSignatureResolver); this.javaDescriptorResolver.setNamespaceFactory(namespaceFactory); this.javaDescriptorResolver.setProject(project); this.javaDescriptorResolver.setPsiClassFinder(psiClassFinderForJvm); @@ -85,6 +89,9 @@ public class InjectorForJavaSemanticServices { javaTypeTransformer.setJavaSemanticServices(javaSemanticServices); javaTypeTransformer.setResolver(javaDescriptorResolver); + javaDescriptorSignatureResolver.setJavaDescriptorResolver(javaDescriptorResolver); + javaDescriptorSignatureResolver.setJavaSemanticServices(javaSemanticServices); + namespaceFactory.setConfiguration(javaBridgeConfiguration); namespaceFactory.setModuleDescriptor(moduleDescriptor); namespaceFactory.setTrace(bindingTrace); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index 43d976d69a2..97c3b356f68 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -49,6 +49,7 @@ import org.jetbrains.jet.lang.resolve.TypeHierarchyResolver; import org.jetbrains.jet.lang.resolve.ScriptBodyResolver; import org.jetbrains.jet.lang.resolve.java.JavaSemanticServices; import org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorSignatureResolver; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -92,6 +93,7 @@ public class InjectorForTopDownAnalyzerForJvm { private ScriptBodyResolver scriptBodyResolver; private JavaSemanticServices javaSemanticServices; private JavaTypeTransformer javaTypeTransformer; + private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver; public InjectorForTopDownAnalyzerForJvm( @NotNull Project project, @@ -132,6 +134,7 @@ public class InjectorForTopDownAnalyzerForJvm { this.scriptBodyResolver = new ScriptBodyResolver(); this.javaSemanticServices = new JavaSemanticServices(); this.javaTypeTransformer = new JavaTypeTransformer(); + this.javaDescriptorSignatureResolver = new JavaDescriptorSignatureResolver(); this.topDownAnalyzer.setBodyResolver(bodyResolver); this.topDownAnalyzer.setContext(topDownAnalysisContext); @@ -169,6 +172,7 @@ public class InjectorForTopDownAnalyzerForJvm { this.javaBridgeConfiguration.setMode(compilerSpecialMode); this.javaBridgeConfiguration.setProject(project); + javaDescriptorResolver.setJavaDescriptorSignatureResolver(javaDescriptorSignatureResolver); javaDescriptorResolver.setNamespaceFactory(namespaceFactory); javaDescriptorResolver.setProject(project); javaDescriptorResolver.setPsiClassFinder(psiClassFinderForJvm); @@ -246,6 +250,9 @@ public class InjectorForTopDownAnalyzerForJvm { javaTypeTransformer.setJavaSemanticServices(javaSemanticServices); javaTypeTransformer.setResolver(javaDescriptorResolver); + javaDescriptorSignatureResolver.setJavaDescriptorResolver(javaDescriptorResolver); + javaDescriptorSignatureResolver.setJavaSemanticServices(javaSemanticServices); + javaBridgeConfiguration.init(); psiClassFinderForJvm.initialize(); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 1f311550599..ef326159950 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -77,40 +77,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes } }; - private enum TypeParameterDescriptorOrigin { - JAVA, - KOTLIN, - } - - public static class TypeParameterDescriptorInitialization { - @NotNull - private final TypeParameterDescriptorOrigin origin; - @NotNull - final TypeParameterDescriptorImpl descriptor; - final PsiTypeParameter psiTypeParameter; - @Nullable - private final List upperBoundsForKotlin; - @Nullable - private final List lowerBoundsForKotlin; - - private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter) { - this.origin = TypeParameterDescriptorOrigin.JAVA; - this.descriptor = descriptor; - this.psiTypeParameter = psiTypeParameter; - this.upperBoundsForKotlin = null; - this.lowerBoundsForKotlin = null; - } - - private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter, - List upperBoundsForKotlin, List lowerBoundsForKotlin) { - this.origin = TypeParameterDescriptorOrigin.KOTLIN; - this.descriptor = descriptor; - this.psiTypeParameter = psiTypeParameter; - this.upperBoundsForKotlin = upperBoundsForKotlin; - this.lowerBoundsForKotlin = lowerBoundsForKotlin; - } - } - static abstract class ResolverScopeData { @Nullable @@ -185,7 +151,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes /** Class with instance members */ static class ResolverBinaryClassData extends ResolverScopeData { - private final ClassDescriptorFromJvmBytecode classDescriptor; + final ClassDescriptorFromJvmBytecode classDescriptor; ResolverBinaryClassData(@NotNull PsiClass psiClass, @NotNull FqName fqName, @NotNull ClassDescriptorFromJvmBytecode classDescriptor) { super(psiClass, null, fqName, false, classDescriptor); @@ -199,7 +165,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes static final ResolverBinaryClassData NEGATIVE = new ResolverBinaryClassData(true); - List typeParameters; + List typeParameters; @NotNull public ClassDescriptor getClassDescriptor() { @@ -247,6 +213,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes private NamespaceFactory namespaceFactory; private BindingTrace trace; private PsiClassFinder psiClassFinder; + private JavaDescriptorSignatureResolver javaDescriptorSignatureResolver; @Inject public void setProject(Project project) { @@ -273,6 +240,10 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes this.psiClassFinder = psiClassFinder; } + @Inject + public void setJavaDescriptorSignatureResolver(JavaDescriptorSignatureResolver javaDescriptorSignatureResolver) { + this.javaDescriptorSignatureResolver = javaDescriptorSignatureResolver; + } @Nullable @@ -371,10 +342,10 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes List supertypes = new ArrayList(); - classData.typeParameters = createUninitializedClassTypeParameters(psiClass, classData); + classData.typeParameters = javaDescriptorSignatureResolver.createUninitializedClassTypeParameters(psiClass, classData); List typeParameters = new ArrayList(); - for (TypeParameterDescriptorInitialization typeParameter : classData.typeParameters) { + for (JavaDescriptorSignatureResolver.TypeParameterDescriptorInitialization typeParameter : classData.typeParameters) { typeParameters.add(typeParameter.descriptor); } @@ -394,7 +365,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes classData.classDescriptor.createTypeConstructor(); classData.classDescriptor.setScopeForMemberLookup(new JavaClassMembersScope(semanticServices, classData)); - initializeTypeParameters(classData.typeParameters, classData.classDescriptor, "class " + psiClass.getQualifiedName()); + javaDescriptorSignatureResolver.initializeTypeParameters(classData.typeParameters, classData.classDescriptor, "class " + psiClass.getQualifiedName()); // TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes supertypes.addAll(getSupertypes(new PsiClassWrapper(psiClass), classData, classData.getTypeParameters())); @@ -576,166 +547,13 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return classData.classDescriptor; } - private List createUninitializedClassTypeParameters(PsiClass psiClass, ResolverBinaryClassData classData) { - JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass); - - if (jetClassAnnotation.signature().length() > 0) { - return resolveClassTypeParametersFromJetSignature( - jetClassAnnotation.signature(), psiClass, classData.classDescriptor); - } - - return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters()); - } - - @NotNull - private PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) { - for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) { - if (typeParameter.getName().equals(name)) { - return typeParameter; - } - } - throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found"); - } - - - private boolean isJavaLangObject(JetType type) { + static boolean isJavaLangObject(JetType type) { ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor(); return classifierDescriptor instanceof ClassDescriptor && DescriptorUtils.getFQName(classifierDescriptor).equalsTo(JdkNames.JL_OBJECT.getFqName()); } - private abstract class JetSignatureTypeParameterVisitor extends JetSignatureExceptionsAdapter { - - @NotNull - private final PsiTypeParameterListOwner psiOwner; - @NotNull - private final String name; - @NotNull - private final TypeVariableResolver typeVariableResolver; - @NotNull - private final TypeParameterDescriptorImpl typeParameterDescriptor; - - protected JetSignatureTypeParameterVisitor(PsiTypeParameterListOwner psiOwner, - String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptorImpl typeParameterDescriptor) - { - if (name.isEmpty()) { - throw new IllegalStateException(); - } - - this.psiOwner = psiOwner; - this.name = name; - this.typeVariableResolver = typeVariableResolver; - this.typeParameterDescriptor = typeParameterDescriptor; - } - - List upperBounds = new ArrayList(); - List lowerBounds = new ArrayList(); - - @Override - public JetSignatureVisitor visitClassBound() { - return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) { - @Override - protected void done(@NotNull JetType jetType) { - if (isJavaLangObject(jetType)) { - return; - } - upperBounds.add(jetType); - } - }; - } - - @Override - public JetSignatureVisitor visitInterfaceBound() { - return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) { - @Override - protected void done(@NotNull JetType jetType) { - upperBounds.add(jetType); - } - }; - } - - @Override - public void visitFormalTypeParameterEnd() { - PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name); - TypeParameterDescriptorInitialization typeParameterDescriptorInitialization = new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter, upperBounds, lowerBounds); - done(typeParameterDescriptorInitialization); - } - - protected abstract void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor); - } - - private class JetSignatureTypeParametersVisitor extends JetSignatureExceptionsAdapter { - @NotNull - private final DeclarationDescriptor containingDeclaration; - @NotNull - private final PsiTypeParameterListOwner psiOwner; - - private final List previousTypeParameters = new ArrayList(); - // note changes state in this method - private final TypeVariableResolver typeVariableResolver; - - - private JetSignatureTypeParametersVisitor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameterListOwner psiOwner, @NotNull String context) { - this.containingDeclaration = containingDeclaration; - this.psiOwner = psiOwner; - - this.typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters( - previousTypeParameters, - containingDeclaration, - context); - } - - private int formalTypeParameterIndex = 0; - - - List r = new ArrayList(); - - @Override - public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) { - TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification( - containingDeclaration, - Collections.emptyList(), // TODO: wrong - reified, - JetSignatureUtils.translateVariance(variance), - Name.identifier(name), - formalTypeParameterIndex++); - - previousTypeParameters.add(typeParameter); - - return new JetSignatureTypeParameterVisitor(psiOwner, name, typeVariableResolver, typeParameter) { - @Override - protected void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor) { - r.add(typeParameterDescriptor); - previousTypeParameters.add(typeParameterDescriptor.descriptor); - } - }; - } - } - - /** - * @see #resolveMethodTypeParametersFromJetSignature(String, com.intellij.psi.PsiMethod, org.jetbrains.jet.lang.descriptors.DeclarationDescriptor) - */ - private List resolveClassTypeParametersFromJetSignature(String jetSignature, - final PsiClass clazz, final ClassDescriptor classDescriptor) { - String context = "class " + clazz.getQualifiedName(); - JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(classDescriptor, clazz, context) { - @Override - public JetSignatureVisitor visitSuperclass() { - // TODO - return new JetSignatureAdapter(); - } - - @Override - public JetSignatureVisitor visitInterface() { - // TODO - return new JetSignatureAdapter(); - } - }; - new JetSignatureReader(jetSignature).accept(jetSignatureTypeParametersVisitor); - return jetSignatureTypeParametersVisitor.r; - } - @NotNull private ClassOrNamespaceDescriptor resolveParentDescriptor(@NotNull PsiClass psiClass) { FqName fqName = new FqName(psiClass.getQualifiedName()); @@ -757,75 +575,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return ns; } - private List makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) { - List result = Lists.newArrayList(); - for (PsiTypeParameter typeParameter : typeParameters) { - TypeParameterDescriptorInitialization typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter); - result.add(typeParameterDescriptor); - } - return result; - } - - @NotNull - private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) { - TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification( - containingDeclaration, - Collections.emptyList(), // TODO - false, - Variance.INVARIANT, - Name.identifier(psiTypeParameter.getName()), - psiTypeParameter.getIndex() - ); - return new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter); - } - - private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableResolver typeVariableByPsiResolver) { - TypeParameterDescriptorImpl typeParameterDescriptor = typeParameter.descriptor; - if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) { - List upperBounds = typeParameter.upperBoundsForKotlin; - if (upperBounds.size() == 0){ - typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType()); - } - else { - for (JetType upperBound : typeParameter.upperBoundsForKotlin) { - typeParameterDescriptor.addUpperBound(upperBound); - } - } - - // TODO: lower bounds - } - else { - PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes(); - if (referencedTypes.length == 0){ - typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType()); - } - else if (referencedTypes.length == 1) { - typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0], JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver)); - } - else { - for (PsiClassType referencedType : referencedTypes) { - typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType, JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver)); - } - } - } - typeParameterDescriptor.setInitialized(); - } - - private void initializeTypeParameters(List typeParametersInitialization, @NotNull DeclarationDescriptor typeParametersOwner, @NotNull String context) { - List prevTypeParameters = new ArrayList(); - - List typeParameters = Lists.newArrayList(); - for (TypeParameterDescriptorInitialization typeParameterDescriptor : typeParametersInitialization) { - typeParameters.add(typeParameterDescriptor.descriptor); - } - - for (TypeParameterDescriptorInitialization psiTypeParameter : typeParametersInitialization) { - prevTypeParameters.add(psiTypeParameter.descriptor); - initializeTypeParameter(psiTypeParameter, - TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, typeParametersOwner, context)); - } - } - private Collection getSupertypes(PsiClassWrapper psiClass, ResolverBinaryClassData classData, List typeParameters) { ClassDescriptor classDescriptor = classData.classDescriptor; @@ -1365,14 +1114,14 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes PsiMethodWrapper method = (PsiMethodWrapper) members.setter.getMember(); if (anyMember == members.setter) { - typeParameters = resolveMethodTypeParameters(method, propertyDescriptor); + typeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, propertyDescriptor); } } if (members.getter != null) { PsiMethodWrapper method = (PsiMethodWrapper) members.getter.getMember(); if (anyMember == members.getter) { - typeParameters = resolveMethodTypeParameters(method, propertyDescriptor); + typeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, propertyDescriptor); } } @@ -1587,7 +1336,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes String context = "method " + method.getName() + " in class " + psiClass.getQualifiedName(); - List methodTypeParameters = resolveMethodTypeParameters(method, functionDescriptorImpl); + List methodTypeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method, functionDescriptorImpl); TypeVariableResolver methodTypeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(methodTypeParameters, functionDescriptorImpl, context); @@ -1792,43 +1541,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes } } - private List resolveMethodTypeParameters( - @NotNull PsiMethodWrapper method, - @NotNull DeclarationDescriptor functionDescriptor) { - - List typeParametersIntialization; - if (method.getJetMethod().typeParameters().length() > 0) { - typeParametersIntialization = resolveMethodTypeParametersFromJetSignature( - method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor); - } - else { - typeParametersIntialization = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters()); - } - - String context = "method " + method.getName() + " in class " + method.getPsiMethod().getContainingClass().getQualifiedName(); - initializeTypeParameters(typeParametersIntialization, functionDescriptor, context); - - List typeParameters = Lists.newArrayListWithCapacity(typeParametersIntialization.size()); - - for (TypeParameterDescriptorInitialization tpdi : typeParametersIntialization) { - typeParameters.add(tpdi.descriptor); - } - - return typeParameters; - } - - /** - * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, org.jetbrains.jet.lang.descriptors.ClassDescriptor) - */ - private List resolveMethodTypeParametersFromJetSignature(String jetSignature, - final PsiMethod method, final DeclarationDescriptor functionDescriptor) - { - String context = "method " + method.getName() + " in class " + method.getContainingClass().getQualifiedName(); - JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(functionDescriptor, method, context); - new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(jetSignatureTypeParametersVisitor); - return jetSignatureTypeParametersVisitor.r; - } - private JetType makeReturnType(PsiType returnType, PsiMethodWrapper method, @NotNull TypeVariableResolver typeVariableResolver) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorSignatureResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorSignatureResolver.java new file mode 100644 index 00000000000..8d4adbd72c3 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorSignatureResolver.java @@ -0,0 +1,373 @@ +/* + * Copyright 2010-2012 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.lang.resolve.java; + +import com.google.common.collect.Lists; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassType; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiTypeParameter; +import com.intellij.psi.PsiTypeParameterListOwner; +import jet.typeinfo.TypeInfoVariance; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptorImpl; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; +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.JetStandardClasses; +import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; +import org.jetbrains.jet.rt.signature.JetSignatureAdapter; +import org.jetbrains.jet.rt.signature.JetSignatureExceptionsAdapter; +import org.jetbrains.jet.rt.signature.JetSignatureReader; +import org.jetbrains.jet.rt.signature.JetSignatureVisitor; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Stepan Koltsov + */ +public class JavaDescriptorSignatureResolver { + + @NotNull + private JavaDescriptorResolver javaDescriptorResolver; + @NotNull + private JavaSemanticServices semanticServices; + + @Inject + public void setJavaDescriptorResolver(@NotNull JavaDescriptorResolver javaDescriptorResolver) { + this.javaDescriptorResolver = javaDescriptorResolver; + } + + @Inject + public void setJavaSemanticServices(@NotNull JavaSemanticServices javaSemanticServices) { + this.semanticServices = javaSemanticServices; + } + + + + private enum TypeParameterDescriptorOrigin { + JAVA, + KOTLIN, + } + + public static class TypeParameterDescriptorInitialization { + @NotNull + private final TypeParameterDescriptorOrigin origin; + @NotNull + final TypeParameterDescriptorImpl descriptor; + final PsiTypeParameter psiTypeParameter; + @Nullable + private final List upperBoundsForKotlin; + @Nullable + private final List lowerBoundsForKotlin; + + private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter) { + this.origin = TypeParameterDescriptorOrigin.JAVA; + this.descriptor = descriptor; + this.psiTypeParameter = psiTypeParameter; + this.upperBoundsForKotlin = null; + this.lowerBoundsForKotlin = null; + } + + private TypeParameterDescriptorInitialization(@NotNull TypeParameterDescriptorImpl descriptor, @NotNull PsiTypeParameter psiTypeParameter, + List upperBoundsForKotlin, List lowerBoundsForKotlin) { + this.origin = TypeParameterDescriptorOrigin.KOTLIN; + this.descriptor = descriptor; + this.psiTypeParameter = psiTypeParameter; + this.upperBoundsForKotlin = upperBoundsForKotlin; + this.lowerBoundsForKotlin = lowerBoundsForKotlin; + } + } + + + + @NotNull + private static PsiTypeParameter getPsiTypeParameterByName(PsiTypeParameterListOwner clazz, String name) { + for (PsiTypeParameter typeParameter : clazz.getTypeParameters()) { + if (typeParameter.getName().equals(name)) { + return typeParameter; + } + } + throw new IllegalStateException("PsiTypeParameter '" + name + "' is not found"); + } + + + + private abstract class JetSignatureTypeParameterVisitor extends JetSignatureExceptionsAdapter { + + @NotNull + private final PsiTypeParameterListOwner psiOwner; + @NotNull + private final String name; + @NotNull + private final TypeVariableResolver typeVariableResolver; + @NotNull + private final TypeParameterDescriptorImpl typeParameterDescriptor; + + protected JetSignatureTypeParameterVisitor(PsiTypeParameterListOwner psiOwner, + String name, TypeVariableResolver typeVariableResolver, TypeParameterDescriptorImpl typeParameterDescriptor) + { + if (name.isEmpty()) { + throw new IllegalStateException(); + } + + this.psiOwner = psiOwner; + this.name = name; + this.typeVariableResolver = typeVariableResolver; + this.typeParameterDescriptor = typeParameterDescriptor; + } + + List upperBounds = new ArrayList(); + List lowerBounds = new ArrayList(); + + @Override + public JetSignatureVisitor visitClassBound() { + return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) { + @Override + protected void done(@NotNull JetType jetType) { + if (JavaDescriptorResolver.isJavaLangObject(jetType)) { + return; + } + upperBounds.add(jetType); + } + }; + } + + @Override + public JetSignatureVisitor visitInterfaceBound() { + return new JetTypeJetSignatureReader(semanticServices, JetStandardLibrary.getInstance(), typeVariableResolver) { + @Override + protected void done(@NotNull JetType jetType) { + upperBounds.add(jetType); + } + }; + } + + @Override + public void visitFormalTypeParameterEnd() { + PsiTypeParameter psiTypeParameter = getPsiTypeParameterByName(psiOwner, name); + TypeParameterDescriptorInitialization typeParameterDescriptorInitialization = new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter, upperBounds, lowerBounds); + done(typeParameterDescriptorInitialization); + } + + protected abstract void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor); + } + + private class JetSignatureTypeParametersVisitor extends JetSignatureExceptionsAdapter { + @NotNull + private final DeclarationDescriptor containingDeclaration; + @NotNull + private final PsiTypeParameterListOwner psiOwner; + + private final List previousTypeParameters = new ArrayList(); + // note changes state in this method + private final TypeVariableResolver typeVariableResolver; + + + private JetSignatureTypeParametersVisitor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameterListOwner psiOwner, @NotNull String context) { + this.containingDeclaration = containingDeclaration; + this.psiOwner = psiOwner; + + this.typeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters( + previousTypeParameters, + containingDeclaration, + context); + } + + private int formalTypeParameterIndex = 0; + + + List r = new ArrayList(); + + @Override + public JetSignatureVisitor visitFormalTypeParameter(final String name, final TypeInfoVariance variance, boolean reified) { + TypeParameterDescriptorImpl typeParameter = TypeParameterDescriptorImpl.createForFurtherModification( + containingDeclaration, + Collections.emptyList(), // TODO: wrong + reified, + JetSignatureUtils.translateVariance(variance), + Name.identifier(name), + formalTypeParameterIndex++); + + previousTypeParameters.add(typeParameter); + + return new JetSignatureTypeParameterVisitor(psiOwner, name, typeVariableResolver, typeParameter) { + @Override + protected void done(@NotNull TypeParameterDescriptorInitialization typeParameterDescriptor) { + r.add(typeParameterDescriptor); + previousTypeParameters.add(typeParameterDescriptor.descriptor); + } + }; + } + } + + /** + * @see #resolveMethodTypeParametersFromJetSignature(String, com.intellij.psi.PsiMethod, org.jetbrains.jet.lang.descriptors.DeclarationDescriptor) + */ + private List resolveClassTypeParametersFromJetSignature(String jetSignature, + final PsiClass clazz, final ClassDescriptor classDescriptor) { + String context = "class " + clazz.getQualifiedName(); + JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(classDescriptor, clazz, context) { + @Override + public JetSignatureVisitor visitSuperclass() { + // TODO + return new JetSignatureAdapter(); + } + + @Override + public JetSignatureVisitor visitInterface() { + // TODO + return new JetSignatureAdapter(); + } + }; + new JetSignatureReader(jetSignature).accept(jetSignatureTypeParametersVisitor); + return jetSignatureTypeParametersVisitor.r; + } + + + private List makeUninitializedTypeParameters(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter[] typeParameters) { + List result = Lists.newArrayList(); + for (PsiTypeParameter typeParameter : typeParameters) { + TypeParameterDescriptorInitialization typeParameterDescriptor = makeUninitializedTypeParameter(containingDeclaration, typeParameter); + result.add(typeParameterDescriptor); + } + return result; + } + + @NotNull + private TypeParameterDescriptorInitialization makeUninitializedTypeParameter(@NotNull DeclarationDescriptor containingDeclaration, @NotNull PsiTypeParameter psiTypeParameter) { + TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification( + containingDeclaration, + Collections.emptyList(), // TODO + false, + Variance.INVARIANT, + Name.identifier(psiTypeParameter.getName()), + psiTypeParameter.getIndex() + ); + return new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter); + } + + private void initializeTypeParameter(TypeParameterDescriptorInitialization typeParameter, TypeVariableResolver typeVariableByPsiResolver) { + TypeParameterDescriptorImpl typeParameterDescriptor = typeParameter.descriptor; + if (typeParameter.origin == TypeParameterDescriptorOrigin.KOTLIN) { + List upperBounds = typeParameter.upperBoundsForKotlin; + if (upperBounds.size() == 0){ + typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType()); + } + else { + for (JetType upperBound : typeParameter.upperBoundsForKotlin) { + typeParameterDescriptor.addUpperBound(upperBound); + } + } + + // TODO: lower bounds + } + else { + PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes(); + if (referencedTypes.length == 0){ + typeParameterDescriptor.addUpperBound(JetStandardClasses.getNullableAnyType()); + } + else if (referencedTypes.length == 1) { + typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedTypes[0], JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver)); + } + else { + for (PsiClassType referencedType : referencedTypes) { + typeParameterDescriptor.addUpperBound(semanticServices.getTypeTransformer().transformToType(referencedType, JavaTypeTransformer.TypeUsage.UPPER_BOUND, typeVariableByPsiResolver)); + } + } + } + typeParameterDescriptor.setInitialized(); + } + + void initializeTypeParameters(List typeParametersInitialization, @NotNull DeclarationDescriptor typeParametersOwner, @NotNull String context) { + List prevTypeParameters = new ArrayList(); + + List typeParameters = Lists.newArrayList(); + for (TypeParameterDescriptorInitialization typeParameterDescriptor : typeParametersInitialization) { + typeParameters.add(typeParameterDescriptor.descriptor); + } + + for (TypeParameterDescriptorInitialization psiTypeParameter : typeParametersInitialization) { + prevTypeParameters.add(psiTypeParameter.descriptor); + initializeTypeParameter(psiTypeParameter, + TypeVariableResolvers.typeVariableResolverFromTypeParameters(typeParameters, typeParametersOwner, context)); + } + } + + + List createUninitializedClassTypeParameters(PsiClass psiClass, JavaDescriptorResolver.ResolverBinaryClassData classData) { + JetClassAnnotation jetClassAnnotation = JetClassAnnotation.get(psiClass); + + if (jetClassAnnotation.signature().length() > 0) { + return resolveClassTypeParametersFromJetSignature( + jetClassAnnotation.signature(), psiClass, classData.classDescriptor); + } + + return makeUninitializedTypeParameters(classData.classDescriptor, psiClass.getTypeParameters()); + } + + + List resolveMethodTypeParameters( + @NotNull PsiMethodWrapper method, + @NotNull DeclarationDescriptor functionDescriptor) { + + List typeParametersIntialization; + if (method.getJetMethod().typeParameters().length() > 0) { + typeParametersIntialization = resolveMethodTypeParametersFromJetSignature( + method.getJetMethod().typeParameters(), method.getPsiMethod(), functionDescriptor); + } + else { + typeParametersIntialization = makeUninitializedTypeParameters(functionDescriptor, method.getPsiMethod().getTypeParameters()); + } + + String context = "method " + method.getName() + " in class " + method.getPsiMethod().getContainingClass().getQualifiedName(); + initializeTypeParameters(typeParametersIntialization, functionDescriptor, context); + + List typeParameters = Lists.newArrayListWithCapacity(typeParametersIntialization.size()); + + for (TypeParameterDescriptorInitialization tpdi : typeParametersIntialization) { + typeParameters.add(tpdi.descriptor); + } + + return typeParameters; + } + + /** + * @see #resolveClassTypeParametersFromJetSignature(String, com.intellij.psi.PsiClass, org.jetbrains.jet.lang.descriptors.ClassDescriptor) + */ + private List resolveMethodTypeParametersFromJetSignature(String jetSignature, + final PsiMethod method, final DeclarationDescriptor functionDescriptor) + { + String context = "method " + method.getName() + " in class " + method.getContainingClass().getQualifiedName(); + JetSignatureTypeParametersVisitor jetSignatureTypeParametersVisitor = new JetSignatureTypeParametersVisitor(functionDescriptor, method, context); + new JetSignatureReader(jetSignature).acceptFormalTypeParametersOnly(jetSignatureTypeParametersVisitor); + return jetSignatureTypeParametersVisitor.r; + } + + + + +}