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 }