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 85f5fd862bf..a0661d118a3 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 @@ -19,7 +19,10 @@ package org.jetbrains.jet.lang.resolve.java; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.intellij.openapi.project.Project; -import com.intellij.psi.*; +import com.intellij.psi.PsiAnnotation; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiModifierListOwner; import gnu.trove.THashMap; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; @@ -44,8 +47,6 @@ import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.TypeUtils; -import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import javax.inject.Inject; import java.util.*; @@ -110,6 +111,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes public final FunctionResolver functionResolver = new FunctionResolver(this); public final NamespaceResolver namespaceResolver = new NamespaceResolver(this); private final InnerClassResolver innerClassResolver = new InnerClassResolver(this); + private final ValueParameterResolver valueParameterResolver = new ValueParameterResolver(this); @Inject public void setProject(Project project) { @@ -271,108 +273,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes } } - private enum JvmMethodParameterKind { - REGULAR, - RECEIVER, - TYPE_INFO, - } - - private static class JvmMethodParameterMeaning { - private final JvmMethodParameterKind kind; - private final JetType receiverType; - private final ValueParameterDescriptor valueParameterDescriptor; - - private JvmMethodParameterMeaning( - JvmMethodParameterKind kind, - JetType receiverType, - ValueParameterDescriptor valueParameterDescriptor - ) { - this.kind = kind; - this.receiverType = receiverType; - this.valueParameterDescriptor = valueParameterDescriptor; - } - - public static JvmMethodParameterMeaning receiver(@NotNull JetType receiverType) { - return new JvmMethodParameterMeaning(JvmMethodParameterKind.RECEIVER, receiverType, null); - } - - public static JvmMethodParameterMeaning regular(@NotNull ValueParameterDescriptor valueParameterDescriptor) { - return new JvmMethodParameterMeaning(JvmMethodParameterKind.REGULAR, null, valueParameterDescriptor); - } - - public static JvmMethodParameterMeaning typeInfo() { - return new JvmMethodParameterMeaning(JvmMethodParameterKind.TYPE_INFO, null, null); - } - } - - @NotNull - private JvmMethodParameterMeaning resolveParameterDescriptor( - DeclarationDescriptor containingDeclaration, int i, - PsiParameterWrapper parameter, TypeVariableResolver typeVariableResolver - ) { - - if (parameter.getJetTypeParameter().isDefined()) { - return JvmMethodParameterMeaning.typeInfo(); - } - - PsiType psiType = parameter.getPsiParameter().getType(); - - // TODO: must be very slow, make it lazy? - Name name = Name.identifier(parameter.getPsiParameter().getName() != null ? parameter.getPsiParameter().getName() : "p" + i); - - if (parameter.getJetValueParameter().name().length() > 0) { - name = Name.identifier(parameter.getJetValueParameter().name()); - } - - String typeFromAnnotation = parameter.getJetValueParameter().type(); - boolean receiver = parameter.getJetValueParameter().receiver(); - boolean hasDefaultValue = parameter.getJetValueParameter().hasDefaultValue(); - - JetType outType; - if (typeFromAnnotation.length() > 0) { - outType = semanticServices.getTypeTransformer().transformToType(typeFromAnnotation, typeVariableResolver); - } - else { - outType = semanticServices.getTypeTransformer() - .transformToType(psiType, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, typeVariableResolver); - } - - JetType varargElementType; - if (psiType instanceof PsiEllipsisType) { - varargElementType = JetStandardLibrary.getInstance().getArrayElementType(TypeUtils.makeNotNullable(outType)); - outType = TypeUtils.makeNotNullable(outType); - } - else { - varargElementType = null; - } - - if (receiver) { - return JvmMethodParameterMeaning.receiver(outType); - } - else { - - JetType transformedType; - if (AnnotationResolver - .findAnnotation(parameter.getPsiParameter(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != - null) { - transformedType = TypeUtils.makeNullableAsSpecified(outType, false); - } - else { - transformedType = outType; - } - return JvmMethodParameterMeaning.regular(new ValueParameterDescriptorImpl( - containingDeclaration, - i, - Collections.emptyList(), // TODO - name, - false, - transformedType, - hasDefaultValue, - varargElementType - )); - } - } - public Set resolveFieldGroupByName(@NotNull Name fieldName, @NotNull ResolverScopeData scopeData) { PsiClass psiClass = scopeData.getPsiClass(); @@ -428,29 +328,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes DeclarationDescriptor containingDeclaration, List parameters, TypeVariableResolver typeVariableResolver ) { - List result = new ArrayList(); - JetType receiverType = null; - int indexDelta = 0; - for (int i = 0, parametersLength = parameters.size(); i < parametersLength; i++) { - PsiParameterWrapper parameter = parameters.get(i); - JvmMethodParameterMeaning meaning = - resolveParameterDescriptor(containingDeclaration, i + indexDelta, parameter, typeVariableResolver); - if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) { - // TODO - --indexDelta; - } - else if (meaning.kind == JvmMethodParameterKind.REGULAR) { - result.add(meaning.valueParameterDescriptor); - } - else if (meaning.kind == JvmMethodParameterKind.RECEIVER) { - if (receiverType != null) { - throw new IllegalStateException("more than one receiver"); - } - --indexDelta; - receiverType = meaning.receiverType; - } - } - return new ValueParameterDescriptors(receiverType, result); + return valueParameterResolver.resolveParameterDescriptors(containingDeclaration, parameters, typeVariableResolver); } public List resolveAnnotations(PsiModifierListOwner owner, @NotNull List tasks) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/ValueParameterResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/ValueParameterResolver.java new file mode 100644 index 00000000000..86f1d2c8778 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/ValueParameterResolver.java @@ -0,0 +1,179 @@ +/* + * 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.resolver; + +import com.intellij.psi.PsiEllipsisType; +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptorImpl; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; +import org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver; +import org.jetbrains.jet.lang.resolve.java.wrapper.PsiParameterWrapper; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ValueParameterResolver { + + private final JavaDescriptorResolver javaDescriptorResolver; + + public ValueParameterResolver(JavaDescriptorResolver javaDescriptorResolver) { + this.javaDescriptorResolver = javaDescriptorResolver; + } + + @NotNull + public JvmMethodParameterMeaning resolveParameterDescriptor( + DeclarationDescriptor containingDeclaration, int i, + PsiParameterWrapper parameter, TypeVariableResolver typeVariableResolver + ) { + + if (parameter.getJetTypeParameter().isDefined()) { + return JvmMethodParameterMeaning.typeInfo(); + } + + PsiType psiType = parameter.getPsiParameter().getType(); + + // TODO: must be very slow, make it lazy? + Name name = Name.identifier(parameter.getPsiParameter().getName() != null ? parameter.getPsiParameter().getName() : "p" + i); + + if (parameter.getJetValueParameter().name().length() > 0) { + name = Name.identifier(parameter.getJetValueParameter().name()); + } + + String typeFromAnnotation = parameter.getJetValueParameter().type(); + boolean receiver = parameter.getJetValueParameter().receiver(); + boolean hasDefaultValue = parameter.getJetValueParameter().hasDefaultValue(); + + JetType outType; + if (typeFromAnnotation.length() > 0) { + outType = javaDescriptorResolver.getSemanticServices().getTypeTransformer() + .transformToType(typeFromAnnotation, typeVariableResolver); + } + else { + outType = javaDescriptorResolver.getSemanticServices().getTypeTransformer() + .transformToType(psiType, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, typeVariableResolver); + } + + JetType varargElementType; + if (psiType instanceof PsiEllipsisType) { + varargElementType = JetStandardLibrary.getInstance().getArrayElementType(TypeUtils.makeNotNullable(outType)); + outType = TypeUtils.makeNotNullable(outType); + } + else { + varargElementType = null; + } + + if (receiver) { + return JvmMethodParameterMeaning.receiver(outType); + } + else { + + JetType transformedType; + if (AnnotationResolver + .findAnnotation(parameter.getPsiParameter(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != + null) { + transformedType = TypeUtils.makeNullableAsSpecified(outType, false); + } + else { + transformedType = outType; + } + return JvmMethodParameterMeaning.regular(new ValueParameterDescriptorImpl( + containingDeclaration, + i, + Collections.emptyList(), // TODO + name, + false, + transformedType, + hasDefaultValue, + varargElementType + )); + } + } + + public JavaDescriptorResolver.ValueParameterDescriptors resolveParameterDescriptors( + DeclarationDescriptor containingDeclaration, + List parameters, TypeVariableResolver typeVariableResolver + ) { + List result = new ArrayList(); + JetType receiverType = null; + int indexDelta = 0; + for (int i = 0, parametersLength = parameters.size(); i < parametersLength; i++) { + PsiParameterWrapper parameter = parameters.get(i); + JvmMethodParameterMeaning meaning = + resolveParameterDescriptor(containingDeclaration, i + indexDelta, parameter, typeVariableResolver); + if (meaning.kind == JvmMethodParameterKind.TYPE_INFO) { + // TODO + --indexDelta; + } + else if (meaning.kind == JvmMethodParameterKind.REGULAR) { + result.add(meaning.valueParameterDescriptor); + } + else if (meaning.kind == JvmMethodParameterKind.RECEIVER) { + if (receiverType != null) { + throw new IllegalStateException("more than one receiver"); + } + --indexDelta; + receiverType = meaning.receiverType; + } + } + return new JavaDescriptorResolver.ValueParameterDescriptors(receiverType, result); + } + + public enum JvmMethodParameterKind { + REGULAR, + RECEIVER, + TYPE_INFO, + } + + public static class JvmMethodParameterMeaning { + public final JvmMethodParameterKind kind; + private final JetType receiverType; + private final ValueParameterDescriptor valueParameterDescriptor; + + private JvmMethodParameterMeaning( + JvmMethodParameterKind kind, + JetType receiverType, + ValueParameterDescriptor valueParameterDescriptor + ) { + this.kind = kind; + this.receiverType = receiverType; + this.valueParameterDescriptor = valueParameterDescriptor; + } + + public static JvmMethodParameterMeaning receiver(@NotNull JetType receiverType) { + return new JvmMethodParameterMeaning(JvmMethodParameterKind.RECEIVER, receiverType, null); + } + + public static JvmMethodParameterMeaning regular(@NotNull ValueParameterDescriptor valueParameterDescriptor) { + return new JvmMethodParameterMeaning(JvmMethodParameterKind.REGULAR, null, valueParameterDescriptor); + } + + public static JvmMethodParameterMeaning typeInfo() { + return new JvmMethodParameterMeaning(JvmMethodParameterKind.TYPE_INFO, null, null); + } + } +} \ No newline at end of file