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.java.resolver;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
021 import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
022 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
023 import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
024 import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType;
025 import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
026 import org.jetbrains.jet.lang.resolve.java.structure.JavaType;
027 import org.jetbrains.jet.lang.resolve.java.structure.JavaValueParameter;
028 import org.jetbrains.jet.lang.resolve.name.Name;
029 import org.jetbrains.jet.lang.types.JetType;
030 import org.jetbrains.jet.lang.types.TypeUtils;
031 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
032
033 import javax.inject.Inject;
034 import java.util.ArrayList;
035 import java.util.Collections;
036 import java.util.List;
037
038 public final class JavaValueParameterResolver {
039 private JavaAnnotationResolver annotationResolver;
040 private JavaTypeTransformer typeTransformer;
041
042 @Inject
043 public void setAnnotationResolver(JavaAnnotationResolver annotationResolver) {
044 this.annotationResolver = annotationResolver;
045 }
046
047 @Inject
048 public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
049 this.typeTransformer = typeTransformer;
050 }
051
052 @NotNull
053 private ValueParameterDescriptor resolveValueParameter(
054 @NotNull DeclarationDescriptor containingDeclaration,
055 int i,
056 @NotNull JavaValueParameter parameter,
057 @NotNull TypeVariableResolver typeVariableResolver
058 ) {
059 TypeUsage typeUsage = annotationResolver.hasMutableAnnotation(parameter)
060 ? TypeUsage.MEMBER_SIGNATURE_COVARIANT
061 : TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT;
062
063 JavaType parameterType = parameter.getType();
064
065 JetType varargElementType;
066 JetType outType;
067 if (parameter.isVararg()) {
068 // TODO: test this code
069 assert parameterType instanceof JavaArrayType : "Vararg parameter should be an array: " + parameterType;
070 JetType arrayType = typeTransformer.transformVarargType(((JavaArrayType) parameterType), typeUsage, typeVariableResolver);
071
072 outType = TypeUtils.makeNotNullable(arrayType);
073 varargElementType = KotlinBuiltIns.getInstance().getArrayElementType(outType);
074 }
075 else {
076 JetType transformedType = typeTransformer.transformToType(parameterType, typeUsage, typeVariableResolver);
077 if (transformedType.isNullable() && annotationResolver.hasNotNullAnnotation(parameter)) {
078 transformedType = TypeUtils.makeNotNullable(transformedType);
079 }
080
081 outType = transformedType;
082 varargElementType = null;
083 }
084
085 return new ValueParameterDescriptorImpl(
086 containingDeclaration,
087 i,
088 Collections.<AnnotationDescriptor>emptyList(), // TODO
089 getParameterName(i, parameter), // TODO: must be very slow, make it lazy?
090 outType,
091 false,
092 varargElementType
093 );
094 }
095
096 @NotNull
097 private static Name getParameterName(int number, @NotNull JavaValueParameter parameter) {
098 Name psiParameterName = parameter.getName();
099 return psiParameterName != null ? psiParameterName : Name.identifier("p" + number);
100 }
101
102 @NotNull
103 public List<ValueParameterDescriptor> resolveValueParameters(
104 @NotNull DeclarationDescriptor container,
105 @NotNull JavaMethod method,
106 @NotNull TypeVariableResolver typeVariableResolver
107 ) {
108 List<JavaValueParameter> parameters = method.getValueParameters();
109 List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(parameters.size());
110 for (int i = 0, size = parameters.size(); i < size; i++) {
111 result.add(resolveValueParameter(container, i, parameters.get(i), typeVariableResolver));
112 }
113 return result;
114 }
115 }