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.types.expressions;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
022    import org.jetbrains.jet.lang.psi.JetTypeReference;
023    import org.jetbrains.jet.lang.resolve.BindingContext;
024    import org.jetbrains.jet.lang.resolve.BindingTrace;
025    import org.jetbrains.jet.lang.resolve.PossiblyBareType;
026    import org.jetbrains.jet.lang.types.*;
027    import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
028    
029    import static org.jetbrains.jet.lang.diagnostics.Errors.NO_TYPE_ARGUMENTS_ON_RHS;
030    
031    public class TypeReconstructionUtil {
032        @NotNull
033        public static JetType reconstructBareType(
034                @NotNull JetTypeReference right,
035                @NotNull PossiblyBareType possiblyBareTarget,
036                @Nullable JetType subjectType,
037                @NotNull BindingTrace trace
038        ) {
039            if (subjectType == null) {
040                // Recovery: let's reconstruct as if we were casting from Any, to get some type there
041                subjectType = KotlinBuiltIns.getInstance().getAnyType();
042            }
043            TypeReconstructionResult reconstructionResult = possiblyBareTarget.reconstruct(subjectType);
044            if (!reconstructionResult.isAllArgumentsInferred()) {
045                TypeConstructor typeConstructor = possiblyBareTarget.getBareTypeConstructor();
046                trace.report(NO_TYPE_ARGUMENTS_ON_RHS.on(right,
047                                                         typeConstructor.getParameters().size(),
048                                                         allStarProjectionsString(typeConstructor)));
049            }
050    
051            JetType targetType = reconstructionResult.getResultingType();
052            if (targetType != null) {
053                if (possiblyBareTarget.isBare()) {
054                    trace.record(BindingContext.TYPE, right, targetType);
055                }
056                return targetType;
057            }
058    
059            return ErrorUtils.createErrorType("Failed to reconstruct type: " + right.getText());
060        }
061    
062        @NotNull
063        private static String allStarProjectionsString(@NotNull TypeConstructor constructor) {
064            int size = constructor.getParameters().size();
065            assert size != 0 : "No projections possible for a nilary type constructor" + constructor;
066            ClassifierDescriptor declarationDescriptor = constructor.getDeclarationDescriptor();
067            assert declarationDescriptor != null : "No declaration descriptor for type constructor " + constructor;
068            String name = declarationDescriptor.getName().asString();
069    
070            return TypeUtils.getTypeNameAndStarProjectionsString(name, size);
071        }
072    }