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.TypeParameterDescriptor;
022    import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
023    import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
024    import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifierType;
025    import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter;
026    import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameterListOwner;
027    import org.jetbrains.jet.lang.types.Variance;
028    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
029    
030    import javax.inject.Inject;
031    import java.util.*;
032    
033    public final class JavaTypeParameterResolver {
034        @NotNull
035        private JavaTypeTransformer typeTransformer;
036    
037        @Inject
038        public void setTypeTransformer(@NotNull JavaTypeTransformer javaTypeTransformer) {
039            this.typeTransformer = javaTypeTransformer;
040        }
041    
042        @NotNull
043        public Initializer resolveTypeParameters(
044                @NotNull DeclarationDescriptor ownerDescriptor,
045                @NotNull JavaTypeParameterListOwner typeParameterListOwner
046        ) {
047            Initializer result = new Initializer(ownerDescriptor);
048            for (JavaTypeParameter typeParameter : typeParameterListOwner.getTypeParameters()) {
049                result.addTypeParameter(typeParameter);
050            }
051            return result;
052        }
053    
054        public class Initializer {
055            private final DeclarationDescriptor owner;
056            private final List<TypeParameterDescriptor> descriptors = new ArrayList<TypeParameterDescriptor>();
057            private final List<JavaTypeParameter> javaTypeParameters = new ArrayList<JavaTypeParameter>();
058    
059            private Initializer(@NotNull DeclarationDescriptor owner) {
060                this.owner = owner;
061            }
062    
063            private void addTypeParameter(@NotNull JavaTypeParameter typeParameter) {
064                TypeParameterDescriptorImpl descriptor = TypeParameterDescriptorImpl.createForFurtherModification(
065                        owner,
066                        Collections.<AnnotationDescriptor>emptyList(), // TODO
067                        false,
068                        Variance.INVARIANT,
069                        typeParameter.getName(),
070                        typeParameter.getIndex()
071                );
072    
073                descriptors.add(descriptor);
074                javaTypeParameters.add(typeParameter);
075            }
076    
077            @NotNull
078            public List<TypeParameterDescriptor> getDescriptors() {
079                return descriptors;
080            }
081    
082            public void initialize() {
083                TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(getDescriptors(), owner);
084    
085                Iterator<TypeParameterDescriptor> descriptorIterator = descriptors.iterator();
086                Iterator<JavaTypeParameter> typeParameterIterator = javaTypeParameters.iterator();
087    
088                while (descriptorIterator.hasNext()) {
089                    TypeParameterDescriptorImpl descriptor = (TypeParameterDescriptorImpl) descriptorIterator.next();
090                    Collection<JavaClassifierType> upperBounds = typeParameterIterator.next().getUpperBounds();
091    
092                    if (upperBounds.isEmpty()) {
093                        descriptor.addUpperBound(KotlinBuiltIns.getInstance().getDefaultBound());
094                    }
095                    else {
096                        for (JavaClassifierType upperBound : upperBounds) {
097                            descriptor.addUpperBound(typeTransformer.transformToType(upperBound, TypeUsage.UPPER_BOUND, typeVariableResolver));
098                        }
099                    }
100                    descriptor.setInitialized();
101                }
102            }
103        }
104    }