001    /*
002     * Copyright 2010-2015 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.kotlin.resolve.jvm.kotlinSignature;
018    
019    import com.intellij.psi.PsiElement;
020    import com.intellij.psi.PsiErrorElement;
021    import org.jetbrains.annotations.NotNull;
022    import org.jetbrains.annotations.Nullable;
023    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
024    import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
025    import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
026    import org.jetbrains.kotlin.psi.JetTypeElement;
027    import org.jetbrains.kotlin.psi.JetTypeReference;
028    import org.jetbrains.kotlin.renderer.DescriptorRenderer;
029    import org.jetbrains.kotlin.resolve.AnalyzingUtils;
030    import org.jetbrains.kotlin.types.JetType;
031    
032    import java.util.List;
033    import java.util.Map;
034    
035    import static org.jetbrains.kotlin.load.java.components.TypeUsage.MEMBER_SIGNATURE_COVARIANT;
036    
037    public abstract class ElementAlternativeSignatureData {
038        private String error;
039        private boolean isAnnotated;
040    
041        public final boolean hasErrors() {
042            return error != null;
043        }
044    
045        @NotNull
046        public final String getError() {
047            if (error == null) {
048                throw new IllegalStateException("There are no errors");
049            }
050            return error;
051        }
052    
053        protected final void setError(@Nullable String error) {
054            this.error = error;
055        }
056    
057        public boolean isAnnotated() {
058            return this.isAnnotated;
059        }
060    
061        protected final void checkForErrors() {
062            if (!isAnnotated() || hasErrors()) {
063                throw new IllegalStateException("Trying to read result while there is none");
064            }
065        }
066    
067        protected final void setAnnotated(boolean isAnnotated) {
068            this.isAnnotated = isAnnotated;
069        }
070    
071        protected static void checkForSyntaxErrors(PsiElement namedElement) {
072            List<PsiErrorElement> syntaxErrors = AnalyzingUtils.getSyntaxErrorRanges(namedElement);
073    
074            if (!syntaxErrors.isEmpty()) {
075                int errorOffset = syntaxErrors.get(0).getTextOffset();
076                String syntaxErrorDescription = syntaxErrors.get(0).getErrorDescription();
077    
078                if (syntaxErrors.size() == 1) {
079                    throw new AlternativeSignatureMismatchException("Alternative signature has syntax error at %d: %s",
080                                                                    errorOffset, syntaxErrorDescription);
081                }
082                else {
083                    throw new AlternativeSignatureMismatchException("Alternative signature has %d syntax errors, first is at %d: %s",
084                                                                    syntaxErrors.size(), errorOffset, syntaxErrorDescription);
085                }
086            }
087        }
088    
089        protected static JetType computeReturnType(
090                @NotNull JetType originalType,
091                @Nullable JetTypeReference altReturnTypeReference,
092                @NotNull Map<TypeParameterDescriptor, TypeParameterDescriptorImpl> originalToAltTypeParameters) {
093            if (altReturnTypeReference == null) {
094                if (KotlinBuiltIns.isUnit(originalType)) {
095                    return originalType;
096                }
097                else {
098                    throw new AlternativeSignatureMismatchException(
099                            "Return type in alternative signature is missing, while in real signature it is '%s'",
100                            DescriptorRenderer.FQ_NAMES_IN_TYPES.renderType(originalType));
101                }
102            }
103    
104            JetTypeElement typeElement = altReturnTypeReference.getTypeElement();
105            assert (typeElement != null);
106    
107            return TypeTransformingVisitor.computeType(typeElement, originalType, originalToAltTypeParameters, MEMBER_SIGNATURE_COVARIANT);
108        }
109    }