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
017package org.jetbrains.jet.lang.resolve.java;
018
019import org.jetbrains.annotations.NotNull;
020import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
021import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
022import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
023
024import java.util.List;
025
026public class TypeVariableResolverFromTypeDescriptors implements TypeVariableResolver {
027
028    @NotNull
029    private final List<TypeParameterDescriptor> typeParameters;
030    @NotNull
031    private final DeclarationDescriptor typeParametersOwner;
032    @NotNull
033    private final String context;
034
035    public TypeVariableResolverFromTypeDescriptors(
036            @NotNull List<TypeParameterDescriptor> typeParameters,
037            @NotNull DeclarationDescriptor owner,
038            @NotNull String context) {
039        this.typeParameters = typeParameters;
040        this.typeParametersOwner = owner;
041        this.context = context;
042
043        for (TypeParameterDescriptor typeParameter : typeParameters) {
044            if (typeParameter.getContainingDeclaration() != owner) {
045                throw new IllegalStateException();
046            }
047        }
048    }
049
050    @NotNull
051    @Override
052    public TypeParameterDescriptor getTypeVariable(@NotNull String name) {
053        return getTypeVariable(name, typeParameters, typeParametersOwner, context);
054    }
055
056    @NotNull
057    private static TypeParameterDescriptor getTypeVariable(
058            @NotNull String name,
059            @NotNull List<TypeParameterDescriptor> typeParameters,
060            @NotNull DeclarationDescriptor owner,
061            @NotNull String context) {
062        for (TypeParameterDescriptor typeParameter : typeParameters) {
063            if (typeParameter.getName().asString().equals(name)) {
064                return typeParameter;
065            }
066        }
067
068        DeclarationDescriptor containingDeclaration = owner.getContainingDeclaration();
069        if (containingDeclaration != null) {
070            return getTypeVariable(
071                    name,
072                    TypeVariableResolvers.getTypeParameterDescriptors((ClassOrNamespaceDescriptor) containingDeclaration),
073                    containingDeclaration,
074                    context);
075        }
076        throw new RuntimeException("type parameter not found by name '" + name + "' in " + context);
077    }
078}