Introduce SinceKotlinInfo, load from serialized metadata

This is a way for future compilers to cause previous compilers to report
diagnostics on usages of some declarations. Diagnostic can have a message
(and/or error code), level (error, warning, or completely hide the declaration
from the resolution), and Kotlin version, since which the diagnostic should no
longer be reported
This commit is contained in:
Alexander Udalov
2016-12-14 11:54:55 +03:00
parent 212240a008
commit feeed98323
17 changed files with 5337 additions and 99 deletions
@@ -46,6 +46,11 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkEquals(old.typeTable, new.typeTable)) return false if (!checkEquals(old.typeTable, new.typeTable)) return false
} }
if (old.hasSinceKotlinInfoTable() != new.hasSinceKotlinInfoTable()) return false
if (old.hasSinceKotlinInfoTable()) {
if (!checkEquals(old.sinceKotlinInfoTable, new.sinceKotlinInfoTable)) return false
}
if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) return false if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) return false
if (old.hasExtension(JvmProtoBuf.packageModuleName)) { if (old.hasExtension(JvmProtoBuf.packageModuleName)) {
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) return false if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) return false
@@ -58,6 +63,7 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
PROPERTY_LIST, PROPERTY_LIST,
TYPE_ALIAS_LIST, TYPE_ALIAS_LIST,
TYPE_TABLE, TYPE_TABLE,
SINCE_KOTLIN_INFO_TABLE,
PACKAGE_MODULE_NAME PACKAGE_MODULE_NAME
} }
@@ -75,6 +81,11 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkEquals(old.typeTable, new.typeTable)) result.add(ProtoBufPackageKind.TYPE_TABLE) if (!checkEquals(old.typeTable, new.typeTable)) result.add(ProtoBufPackageKind.TYPE_TABLE)
} }
if (old.hasSinceKotlinInfoTable() != new.hasSinceKotlinInfoTable()) result.add(ProtoBufPackageKind.SINCE_KOTLIN_INFO_TABLE)
if (old.hasSinceKotlinInfoTable()) {
if (!checkEquals(old.sinceKotlinInfoTable, new.sinceKotlinInfoTable)) result.add(ProtoBufPackageKind.SINCE_KOTLIN_INFO_TABLE)
}
if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME) if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
if (old.hasExtension(JvmProtoBuf.packageModuleName)) { if (old.hasExtension(JvmProtoBuf.packageModuleName)) {
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME) if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
@@ -119,6 +130,16 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkEquals(old.typeTable, new.typeTable)) return false if (!checkEquals(old.typeTable, new.typeTable)) return false
} }
if (old.hasSinceKotlinInfo() != new.hasSinceKotlinInfo()) return false
if (old.hasSinceKotlinInfo()) {
if (old.sinceKotlinInfo != new.sinceKotlinInfo) return false
}
if (old.hasSinceKotlinInfoTable() != new.hasSinceKotlinInfoTable()) return false
if (old.hasSinceKotlinInfoTable()) {
if (!checkEquals(old.sinceKotlinInfoTable, new.sinceKotlinInfoTable)) return false
}
if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) return false if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) return false
if (old.hasExtension(JvmProtoBuf.classModuleName)) { if (old.hasExtension(JvmProtoBuf.classModuleName)) {
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) return false if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) return false
@@ -140,6 +161,8 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
TYPE_ALIAS_LIST, TYPE_ALIAS_LIST,
ENUM_ENTRY_LIST, ENUM_ENTRY_LIST,
TYPE_TABLE, TYPE_TABLE,
SINCE_KOTLIN_INFO,
SINCE_KOTLIN_INFO_TABLE,
CLASS_MODULE_NAME CLASS_MODULE_NAME
} }
@@ -181,6 +204,16 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkEquals(old.typeTable, new.typeTable)) result.add(ProtoBufClassKind.TYPE_TABLE) if (!checkEquals(old.typeTable, new.typeTable)) result.add(ProtoBufClassKind.TYPE_TABLE)
} }
if (old.hasSinceKotlinInfo() != new.hasSinceKotlinInfo()) result.add(ProtoBufClassKind.SINCE_KOTLIN_INFO)
if (old.hasSinceKotlinInfo()) {
if (old.sinceKotlinInfo != new.sinceKotlinInfo) result.add(ProtoBufClassKind.SINCE_KOTLIN_INFO)
}
if (old.hasSinceKotlinInfoTable() != new.hasSinceKotlinInfoTable()) result.add(ProtoBufClassKind.SINCE_KOTLIN_INFO_TABLE)
if (old.hasSinceKotlinInfoTable()) {
if (!checkEquals(old.sinceKotlinInfoTable, new.sinceKotlinInfoTable)) result.add(ProtoBufClassKind.SINCE_KOTLIN_INFO_TABLE)
}
if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) result.add(ProtoBufClassKind.CLASS_MODULE_NAME) if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
if (old.hasExtension(JvmProtoBuf.classModuleName)) { if (old.hasExtension(JvmProtoBuf.classModuleName)) {
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.CLASS_MODULE_NAME) if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
@@ -231,6 +264,11 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkEquals(old.typeTable, new.typeTable)) return false if (!checkEquals(old.typeTable, new.typeTable)) return false
} }
if (old.hasSinceKotlinInfo() != new.hasSinceKotlinInfo()) return false
if (old.hasSinceKotlinInfo()) {
if (old.sinceKotlinInfo != new.sinceKotlinInfo) return false
}
if (old.hasExtension(JvmProtoBuf.methodSignature) != new.hasExtension(JvmProtoBuf.methodSignature)) return false if (old.hasExtension(JvmProtoBuf.methodSignature) != new.hasExtension(JvmProtoBuf.methodSignature)) return false
if (old.hasExtension(JvmProtoBuf.methodSignature)) { if (old.hasExtension(JvmProtoBuf.methodSignature)) {
if (!checkEquals(old.getExtension(JvmProtoBuf.methodSignature), new.getExtension(JvmProtoBuf.methodSignature))) return false if (!checkEquals(old.getExtension(JvmProtoBuf.methodSignature), new.getExtension(JvmProtoBuf.methodSignature))) return false
@@ -289,6 +327,11 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (old.setterFlags != new.setterFlags) return false if (old.setterFlags != new.setterFlags) return false
} }
if (old.hasSinceKotlinInfo() != new.hasSinceKotlinInfo()) return false
if (old.hasSinceKotlinInfo()) {
if (old.sinceKotlinInfo != new.sinceKotlinInfo) return false
}
if (old.hasExtension(JvmProtoBuf.propertySignature) != new.hasExtension(JvmProtoBuf.propertySignature)) return false if (old.hasExtension(JvmProtoBuf.propertySignature) != new.hasExtension(JvmProtoBuf.propertySignature)) return false
if (old.hasExtension(JvmProtoBuf.propertySignature)) { if (old.hasExtension(JvmProtoBuf.propertySignature)) {
if (!checkEquals(old.getExtension(JvmProtoBuf.propertySignature), new.getExtension(JvmProtoBuf.propertySignature))) return false if (!checkEquals(old.getExtension(JvmProtoBuf.propertySignature), new.getExtension(JvmProtoBuf.propertySignature))) return false
@@ -329,6 +372,11 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkEqualsTypeAliasAnnotation(old, new)) return false if (!checkEqualsTypeAliasAnnotation(old, new)) return false
if (old.hasSinceKotlinInfo() != new.hasSinceKotlinInfo()) return false
if (old.hasSinceKotlinInfo()) {
if (old.sinceKotlinInfo != new.sinceKotlinInfo) return false
}
return true return true
} }
@@ -343,6 +391,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
return true return true
} }
open fun checkEquals(old: ProtoBuf.SinceKotlinInfoTable, new: ProtoBuf.SinceKotlinInfoTable): Boolean {
if (!checkEqualsSinceKotlinInfoTableInfo(old, new)) return false
return true
}
open fun checkEquals(old: ProtoBuf.TypeParameter, new: ProtoBuf.TypeParameter): Boolean { open fun checkEquals(old: ProtoBuf.TypeParameter, new: ProtoBuf.TypeParameter): Boolean {
if (old.id != new.id) return false if (old.id != new.id) return false
@@ -456,6 +510,11 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkEqualsConstructorValueParameter(old, new)) return false if (!checkEqualsConstructorValueParameter(old, new)) return false
if (old.hasSinceKotlinInfo() != new.hasSinceKotlinInfo()) return false
if (old.hasSinceKotlinInfo()) {
if (old.sinceKotlinInfo != new.sinceKotlinInfo) return false
}
if (old.hasExtension(JvmProtoBuf.constructorSignature) != new.hasExtension(JvmProtoBuf.constructorSignature)) return false if (old.hasExtension(JvmProtoBuf.constructorSignature) != new.hasExtension(JvmProtoBuf.constructorSignature)) return false
if (old.hasExtension(JvmProtoBuf.constructorSignature)) { if (old.hasExtension(JvmProtoBuf.constructorSignature)) {
if (!checkEquals(old.getExtension(JvmProtoBuf.constructorSignature), new.getExtension(JvmProtoBuf.constructorSignature))) return false if (!checkEquals(old.getExtension(JvmProtoBuf.constructorSignature), new.getExtension(JvmProtoBuf.constructorSignature))) return false
@@ -550,6 +609,35 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
return true return true
} }
open fun checkEquals(old: ProtoBuf.SinceKotlinInfo, new: ProtoBuf.SinceKotlinInfo): Boolean {
if (old.hasVersion() != new.hasVersion()) return false
if (old.hasVersion()) {
if (old.version != new.version) return false
}
if (old.hasVersionFull() != new.hasVersionFull()) return false
if (old.hasVersionFull()) {
if (old.versionFull != new.versionFull) return false
}
if (old.hasLevel() != new.hasLevel()) return false
if (old.hasLevel()) {
if (old.level != new.level) return false
}
if (old.hasErrorCode() != new.hasErrorCode()) return false
if (old.hasErrorCode()) {
if (old.errorCode != new.errorCode) return false
}
if (old.hasMessage() != new.hasMessage()) return false
if (old.hasMessage()) {
if (!checkStringEquals(old.message, new.message)) return false
}
return true
}
open fun checkEquals(old: ProtoBuf.Type.Argument, new: ProtoBuf.Type.Argument): Boolean { open fun checkEquals(old: ProtoBuf.Type.Argument, new: ProtoBuf.Type.Argument): Boolean {
if (old.hasProjection() != new.hasProjection()) return false if (old.hasProjection() != new.hasProjection()) return false
if (old.hasProjection()) { if (old.hasProjection()) {
@@ -817,6 +905,16 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
return true return true
} }
open fun checkEqualsSinceKotlinInfoTableInfo(old: ProtoBuf.SinceKotlinInfoTable, new: ProtoBuf.SinceKotlinInfoTable): Boolean {
if (old.infoCount != new.infoCount) return false
for(i in 0..old.infoCount - 1) {
if (!checkEquals(old.getInfo(i), new.getInfo(i))) return false
}
return true
}
open fun checkEqualsTypeParameterUpperBound(old: ProtoBuf.TypeParameter, new: ProtoBuf.TypeParameter): Boolean { open fun checkEqualsTypeParameterUpperBound(old: ProtoBuf.TypeParameter, new: ProtoBuf.TypeParameter): Boolean {
if (old.upperBoundCount != new.upperBoundCount) return false if (old.upperBoundCount != new.upperBoundCount) return false
@@ -927,6 +1025,10 @@ fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
hashCode = 31 * hashCode + typeTable.hashCode(stringIndexes, fqNameIndexes) hashCode = 31 * hashCode + typeTable.hashCode(stringIndexes, fqNameIndexes)
} }
if (hasSinceKotlinInfoTable()) {
hashCode = 31 * hashCode + sinceKotlinInfoTable.hashCode(stringIndexes, fqNameIndexes)
}
if (hasExtension(JvmProtoBuf.packageModuleName)) { if (hasExtension(JvmProtoBuf.packageModuleName)) {
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.packageModuleName)) hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.packageModuleName))
} }
@@ -987,6 +1089,14 @@ fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) ->
hashCode = 31 * hashCode + typeTable.hashCode(stringIndexes, fqNameIndexes) hashCode = 31 * hashCode + typeTable.hashCode(stringIndexes, fqNameIndexes)
} }
if (hasSinceKotlinInfo()) {
hashCode = 31 * hashCode + sinceKotlinInfo
}
if (hasSinceKotlinInfoTable()) {
hashCode = 31 * hashCode + sinceKotlinInfoTable.hashCode(stringIndexes, fqNameIndexes)
}
if (hasExtension(JvmProtoBuf.classModuleName)) { if (hasExtension(JvmProtoBuf.classModuleName)) {
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.classModuleName)) hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.classModuleName))
} }
@@ -1035,6 +1145,10 @@ fun ProtoBuf.Function.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
hashCode = 31 * hashCode + typeTable.hashCode(stringIndexes, fqNameIndexes) hashCode = 31 * hashCode + typeTable.hashCode(stringIndexes, fqNameIndexes)
} }
if (hasSinceKotlinInfo()) {
hashCode = 31 * hashCode + sinceKotlinInfo
}
if (hasExtension(JvmProtoBuf.methodSignature)) { if (hasExtension(JvmProtoBuf.methodSignature)) {
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.methodSignature).hashCode(stringIndexes, fqNameIndexes) hashCode = 31 * hashCode + getExtension(JvmProtoBuf.methodSignature).hashCode(stringIndexes, fqNameIndexes)
} }
@@ -1087,6 +1201,10 @@ fun ProtoBuf.Property.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
hashCode = 31 * hashCode + setterFlags hashCode = 31 * hashCode + setterFlags
} }
if (hasSinceKotlinInfo()) {
hashCode = 31 * hashCode + sinceKotlinInfo
}
if (hasExtension(JvmProtoBuf.propertySignature)) { if (hasExtension(JvmProtoBuf.propertySignature)) {
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.propertySignature).hashCode(stringIndexes, fqNameIndexes) hashCode = 31 * hashCode + getExtension(JvmProtoBuf.propertySignature).hashCode(stringIndexes, fqNameIndexes)
} }
@@ -1127,6 +1245,10 @@ fun ProtoBuf.TypeAlias.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int
hashCode = 31 * hashCode + getAnnotation(i).hashCode(stringIndexes, fqNameIndexes) hashCode = 31 * hashCode + getAnnotation(i).hashCode(stringIndexes, fqNameIndexes)
} }
if (hasSinceKotlinInfo()) {
hashCode = 31 * hashCode + sinceKotlinInfo
}
return hashCode return hashCode
} }
@@ -1144,6 +1266,16 @@ fun ProtoBuf.TypeTable.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int
return hashCode return hashCode
} }
fun ProtoBuf.SinceKotlinInfoTable.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1
for(i in 0..infoCount - 1) {
hashCode = 31 * hashCode + getInfo(i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
fun ProtoBuf.TypeParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int { fun ProtoBuf.TypeParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1 var hashCode = 1
@@ -1251,6 +1383,10 @@ fun ProtoBuf.Constructor.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (I
hashCode = 31 * hashCode + getValueParameter(i).hashCode(stringIndexes, fqNameIndexes) hashCode = 31 * hashCode + getValueParameter(i).hashCode(stringIndexes, fqNameIndexes)
} }
if (hasSinceKotlinInfo()) {
hashCode = 31 * hashCode + sinceKotlinInfo
}
if (hasExtension(JvmProtoBuf.constructorSignature)) { if (hasExtension(JvmProtoBuf.constructorSignature)) {
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.constructorSignature).hashCode(stringIndexes, fqNameIndexes) hashCode = 31 * hashCode + getExtension(JvmProtoBuf.constructorSignature).hashCode(stringIndexes, fqNameIndexes)
} }
@@ -1344,6 +1480,32 @@ fun ProtoBuf.Annotation.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (In
return hashCode return hashCode
} }
fun ProtoBuf.SinceKotlinInfo.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1
if (hasVersion()) {
hashCode = 31 * hashCode + version
}
if (hasVersionFull()) {
hashCode = 31 * hashCode + versionFull
}
if (hasLevel()) {
hashCode = 31 * hashCode + level.hashCode()
}
if (hasErrorCode()) {
hashCode = 31 * hashCode + errorCode
}
if (hasMessage()) {
hashCode = 31 * hashCode + stringIndexes(message)
}
return hashCode
}
fun ProtoBuf.Type.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int { fun ProtoBuf.Type.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int): Int {
var hashCode = 1 var hashCode = 1
File diff suppressed because it is too large Load Diff
@@ -20,9 +20,11 @@ import com.google.common.collect.ImmutableSet;
import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.impl.source.tree.LeafPsiElement;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.cfg.WhenMissingCase; import org.jetbrains.kotlin.cfg.WhenMissingCase;
import org.jetbrains.kotlin.config.LanguageFeature; import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.config.LanguageVersion;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.lexer.KtKeywordToken; import org.jetbrains.kotlin.lexer.KtKeywordToken;
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken; import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
@@ -79,6 +81,8 @@ public interface Errors {
DiagnosticFactory2<PsiElement, DeclarationDescriptor, String> DEPRECATION = DiagnosticFactory2.create(WARNING); DiagnosticFactory2<PsiElement, DeclarationDescriptor, String> DEPRECATION = DiagnosticFactory2.create(WARNING);
DiagnosticFactory2<PsiElement, DeclarationDescriptor, String> DEPRECATION_ERROR = DiagnosticFactory2.create(ERROR); DiagnosticFactory2<PsiElement, DeclarationDescriptor, String> DEPRECATION_ERROR = DiagnosticFactory2.create(ERROR);
DiagnosticFactory3<PsiElement, DeclarationDescriptor, String, Pair<LanguageVersion, String>> SINCE_KOTLIN_INFO_DEPRECATION = DiagnosticFactory3.create(WARNING);
DiagnosticFactory3<PsiElement, DeclarationDescriptor, String, Pair<LanguageVersion, String>> SINCE_KOTLIN_INFO_DEPRECATION_ERROR = DiagnosticFactory3.create(ERROR);
DiagnosticFactory2<PsiElement, String, String> API_NOT_AVAILABLE = DiagnosticFactory2.create(ERROR); DiagnosticFactory2<PsiElement, String, String> API_NOT_AVAILABLE = DiagnosticFactory2.create(ERROR);
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.diagnostics.rendering;
import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtil;
import kotlin.Pair;
import kotlin.jvm.functions.Function1; import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -320,6 +321,17 @@ public class DefaultErrorMessages {
MAP.put(DEPRECATION, "''{0}'' is deprecated. {1}", DEPRECATION_RENDERER, STRING); MAP.put(DEPRECATION, "''{0}'' is deprecated. {1}", DEPRECATION_RENDERER, STRING);
MAP.put(DEPRECATION_ERROR, "Using ''{0}'' is an error. {1}", DEPRECATION_RENDERER, STRING); MAP.put(DEPRECATION_ERROR, "Using ''{0}'' is an error. {1}", DEPRECATION_RENDERER, STRING);
DiagnosticParameterRenderer<Pair<LanguageVersion, String>> sinceKotlinInfoRenderer = new DiagnosticParameterRenderer<Pair<LanguageVersion, String>>() {
@NotNull
@Override
public String render(@NotNull Pair<LanguageVersion, String> pair, @NotNull RenderingContext renderingContext) {
String message = pair.getSecond();
return pair.getFirst().getVersionString() + (message != null ? ". " + message : "");
}
};
MAP.put(SINCE_KOTLIN_INFO_DEPRECATION, "''{0}'' is only supported since Kotlin {1} and should not be used in Kotlin {2}", DEPRECATION_RENDERER, STRING, sinceKotlinInfoRenderer);
MAP.put(SINCE_KOTLIN_INFO_DEPRECATION_ERROR, "''{0}'' is only available since Kotlin {1} and cannot be used in Kotlin {2}", DEPRECATION_RENDERER, STRING, sinceKotlinInfoRenderer);
MAP.put(API_NOT_AVAILABLE, "This declaration is only available since Kotlin {0} and cannot be used with the specified API version {1}", STRING, STRING); MAP.put(API_NOT_AVAILABLE, "This declaration is only available since Kotlin {0} and cannot be used with the specified API version {1}", STRING, STRING);
MAP.put(MISSING_DEPENDENCY_CLASS, "Cannot access class ''{0}''. Check your module classpath for missing or conflicting dependencies", TO_STRING); MAP.put(MISSING_DEPENDENCY_CLASS, "Cannot access class ''{0}''. Check your module classpath for missing or conflicting dependencies", TO_STRING);
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.tree.TokenSet import com.intellij.psi.tree.TokenSet
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
@@ -35,10 +36,12 @@ import org.jetbrains.kotlin.resolve.getDeprecations
object DeprecatedCallChecker : CallChecker { object DeprecatedCallChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) { override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
check(resolvedCall.resultingDescriptor, context.trace, reportOn) check(resolvedCall.resultingDescriptor, context.trace, reportOn, context.languageVersionSettings)
} }
private fun check(targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement) { private fun check(
targetDescriptor: CallableDescriptor, trace: BindingTrace, element: PsiElement, languageVersionSettings: LanguageVersionSettings
) {
// Objects will be checked by DeprecatedClassifierUsageChecker // Objects will be checked by DeprecatedClassifierUsageChecker
if (targetDescriptor is FakeCallableDescriptorForObject) return if (targetDescriptor is FakeCallableDescriptorForObject) return
@@ -51,11 +54,11 @@ object DeprecatedCallChecker : CallChecker {
if (deprecations.isNotEmpty()) { if (deprecations.isNotEmpty()) {
for (deprecation in deprecations) { for (deprecation in deprecations) {
trace.report(createDeprecationDiagnostic(element, deprecation)) trace.report(createDeprecationDiagnostic(element, deprecation, languageVersionSettings))
} }
} }
else if (targetDescriptor is PropertyDescriptor && shouldCheckPropertyGetter(element)) { else if (targetDescriptor is PropertyDescriptor && shouldCheckPropertyGetter(element)) {
targetDescriptor.getter?.let { check(it, trace, element) } targetDescriptor.getter?.let { check(it, trace, element, languageVersionSettings) }
} }
} }
@@ -32,7 +32,7 @@ class DeprecatedClassifierUsageChecker : ClassifierUsageChecker {
) { ) {
val deprecations = targetDescriptor.getDeprecations() val deprecations = targetDescriptor.getDeprecations()
for (deprecation in deprecations) { for (deprecation in deprecations) {
trace.report(createDeprecationDiagnostic(element, deprecation)) trace.report(createDeprecationDiagnostic(element, deprecation, languageVersionSettings))
} }
} }
} }
@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DeprecationLevelValue.* import org.jetbrains.kotlin.resolve.DeprecationLevelValue.*
import org.jetbrains.kotlin.resolve.annotations.argumentValue import org.jetbrains.kotlin.resolve.annotations.argumentValue
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfo
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
private val JAVA_DEPRECATED = FqName("java.lang.Deprecated") private val JAVA_DEPRECATED = FqName("java.lang.Deprecated")
@@ -89,8 +91,42 @@ private data class DeprecatedByOverridden(private val deprecations: Collection<D
internal fun additionalMessage() = "Overrides deprecated member in '${DescriptorUtils.getContainingClass(target)!!.fqNameSafe.asString()}'" internal fun additionalMessage() = "Overrides deprecated member in '${DescriptorUtils.getContainingClass(target)!!.fqNameSafe.asString()}'"
} }
private data class DeprecatedBySinceKotlinInfo(
private val sinceKotlinInfo: SinceKotlinInfo,
override val target: DeclarationDescriptor
) : Deprecation {
override val deprecationLevel: DeprecationLevelValue
get() = when (sinceKotlinInfo.level) {
DeprecationLevel.WARNING -> WARNING
DeprecationLevel.ERROR -> ERROR
DeprecationLevel.HIDDEN -> HIDDEN
}
override val message: String?
get() {
val message = sinceKotlinInfo.message
val errorCode = sinceKotlinInfo.errorCode
if (message == null && errorCode == null) return null
return buildString {
if (message != null) {
append(message)
if (errorCode != null) {
append(" (error code $errorCode)")
}
}
else {
append("Error code $errorCode")
}
}
}
val sinceKotlinVersion: String
get() = sinceKotlinInfo.version.asString()
}
fun DeclarationDescriptor.getDeprecations(): List<Deprecation> { fun DeclarationDescriptor.getDeprecations(): List<Deprecation> {
val deprecations = this.getDeprecationsByAnnotation() val deprecations = this.getOwnDeprecations()
if (deprecations.isNotEmpty()) { if (deprecations.isNotEmpty()) {
return deprecations return deprecations
} }
@@ -112,7 +148,7 @@ private fun deprecationByOverridden(root: CallableMemberDescriptor): Deprecation
visited.add(node) visited.add(node)
val deprecationsByAnnotation = node.getDeprecationsByAnnotation() val deprecationsByAnnotation = node.getOwnDeprecations()
val overriddenDescriptors = node.original.overriddenDescriptors val overriddenDescriptors = node.original.overriddenDescriptors
when { when {
deprecationsByAnnotation.isNotEmpty() -> { deprecationsByAnnotation.isNotEmpty() -> {
@@ -135,11 +171,11 @@ private fun deprecationByOverridden(root: CallableMemberDescriptor): Deprecation
return DeprecatedByOverridden(deprecations) return DeprecatedByOverridden(deprecations)
} }
private fun DeclarationDescriptor.getDeprecationsByAnnotation(): List<Deprecation> { private fun DeclarationDescriptor.getOwnDeprecations(): List<Deprecation> {
if (this is TypeAliasConstructorDescriptor) { if (this is TypeAliasConstructorDescriptor) {
// Constructor of type alias has no annotations by itself, all its annotations come from the aliased constructor // Constructor of type alias has no annotations by itself, all its annotations come from the aliased constructor
// and from the typealias declaration // and from the typealias declaration
return underlyingConstructorDescriptor.getDeprecationsByAnnotation() + typeAliasDescriptor.getDeprecationsByAnnotation() return underlyingConstructorDescriptor.getOwnDeprecations() + typeAliasDescriptor.getOwnDeprecations()
} }
val result = SmartList<Deprecation>() val result = SmartList<Deprecation>()
@@ -150,6 +186,13 @@ private fun DeclarationDescriptor.getDeprecationsByAnnotation(): List<Deprecatio
if (annotation != null) { if (annotation != null) {
result.add(DeprecatedByAnnotation(annotation, target)) result.add(DeprecatedByAnnotation(annotation, target))
} }
if (target is DeserializedMemberDescriptor) {
val sinceKotlinInfo = target.sinceKotlinInfo
if (sinceKotlinInfo != null) {
result.add(DeprecatedBySinceKotlinInfo(sinceKotlinInfo, target))
}
}
} }
fun addUseSiteTargetedDeprecationIfPresent(annotatedDescriptor: DeclarationDescriptor, useSiteTarget: AnnotationUseSiteTarget?) { fun addUseSiteTargetedDeprecationIfPresent(annotatedDescriptor: DeclarationDescriptor, useSiteTarget: AnnotationUseSiteTarget?) {
@@ -182,14 +225,24 @@ private fun DeclarationDescriptor.getDeprecationsByAnnotation(): List<Deprecatio
return result.distinct() return result.distinct()
} }
internal fun createDeprecationDiagnostic(element: PsiElement, deprecation: Deprecation): Diagnostic { internal fun createDeprecationDiagnostic(
element: PsiElement, deprecation: Deprecation, languageVersionSettings: LanguageVersionSettings
): Diagnostic {
val targetOriginal = deprecation.target.original val targetOriginal = deprecation.target.original
val diagnosticFactory = when (deprecation.deprecationLevel) { if (deprecation is DeprecatedBySinceKotlinInfo) {
WARNING -> Errors.DEPRECATION val factory = when (deprecation.deprecationLevel) {
ERROR -> Errors.DEPRECATION_ERROR WARNING -> Errors.SINCE_KOTLIN_INFO_DEPRECATION
HIDDEN -> Errors.DEPRECATION_ERROR ERROR, HIDDEN -> Errors.SINCE_KOTLIN_INFO_DEPRECATION_ERROR
}
return factory.on(element, targetOriginal, deprecation.sinceKotlinVersion,
languageVersionSettings.languageVersion to deprecation.message)
} }
return diagnosticFactory.on(element, targetOriginal, deprecation.message ?: "")
val factory = when (deprecation.deprecationLevel) {
WARNING -> Errors.DEPRECATION
ERROR, HIDDEN -> Errors.DEPRECATION_ERROR
}
return factory.on(element, targetOriginal, deprecation.message ?: "")
} }
// values from kotlin.DeprecationLevel // values from kotlin.DeprecationLevel
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.config package org.jetbrains.kotlin.config
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfo
class ApiVersion private constructor( class ApiVersion private constructor(
private val version: MavenComparableVersion, private val version: MavenComparableVersion,
val versionString: String val versionString: String
@@ -38,6 +40,10 @@ class ApiVersion private constructor(
@JvmStatic @JvmStatic
fun createByLanguageVersion(version: LanguageVersion): ApiVersion = parse(version.versionString)!! fun createByLanguageVersion(version: LanguageVersion): ApiVersion = parse(version.versionString)!!
@JvmStatic
fun createBySinceKotlinInfo(sinceKotlinInfo: SinceKotlinInfo): ApiVersion =
sinceKotlinInfo.version.let { version -> parse(version.asString()) ?: error("Could not parse version: $version") }
fun parse(versionString: String): ApiVersion? = try { fun parse(versionString: String): ApiVersion? = try {
ApiVersion(MavenComparableVersion(versionString), versionString) ApiVersion(MavenComparableVersion(versionString), versionString)
} }
@@ -203,6 +203,11 @@ message Class {
optional TypeTable type_table = 30; optional TypeTable type_table = 30;
// Index into the SinceKotlinInfoTable
optional int32 sinceKotlinInfo = 31;
optional SinceKotlinInfoTable since_kotlin_info_table = 32;
extensions 100 to 199; extensions 100 to 199;
} }
@@ -213,6 +218,8 @@ message Package {
optional TypeTable type_table = 30; optional TypeTable type_table = 30;
optional SinceKotlinInfoTable since_kotlin_info_table = 32;
extensions 100 to 199; extensions 100 to 199;
} }
@@ -234,6 +241,9 @@ message Constructor {
repeated ValueParameter value_parameter = 2; repeated ValueParameter value_parameter = 2;
// Index into the SinceKotlinInfoTable
optional int32 sinceKotlinInfo = 31;
extensions 100 to 199; extensions 100 to 199;
} }
@@ -266,6 +276,9 @@ message Function {
optional TypeTable type_table = 30; optional TypeTable type_table = 30;
// Index into the SinceKotlinInfoTable
optional int32 sinceKotlinInfo = 31;
extensions 100 to 199; extensions 100 to 199;
} }
@@ -308,6 +321,9 @@ message Property {
optional int32 getter_flags = 7 /* absent => same as property */; optional int32 getter_flags = 7 /* absent => same as property */;
optional int32 setter_flags = 8 /* absent => same as property */; optional int32 setter_flags = 8 /* absent => same as property */;
// Index into the SinceKotlinInfoTable
optional int32 sinceKotlinInfo = 31;
extensions 100 to 199; extensions 100 to 199;
} }
@@ -350,6 +366,9 @@ message TypeAlias {
repeated Annotation annotation = 8; repeated Annotation annotation = 8;
// Index into the SinceKotlinInfoTable
optional int32 sinceKotlinInfo = 31;
extensions 100 to 199; extensions 100 to 199;
} }
@@ -384,3 +403,33 @@ enum MemberKind {
DELEGATION = 2; DELEGATION = 2;
SYNTHESIZED = 3; SYNTHESIZED = 3;
} }
message SinceKotlinInfo {
enum Level {
WARNING = 0;
ERROR = 1;
HIDDEN = 2;
}
// Kotlin version, since which this declaration is accessible, in the following format (encoded version is "major.minor.patch"):
// (patch << 7) + (minor << 3) + major
// Compilers with version less than this value should report a diagnostic if this declaration is selected as the resolution result
optional int32 version = 1;
// Version in base 256, in case we run out of space to store the version in the optimized form. Has priority over 'version'.
// (patch << 16) + (minor << 8) + major
optional int32 version_full = 2;
// Level of the reported diagnostic
optional Level level = 3 [default = ERROR];
// Error code, to be looked up on the website
optional int32 error_code = 4;
// Diagnostic message
optional int32 message = 5 [(string_id_in_table) = true];
}
message SinceKotlinInfoTable {
repeated SinceKotlinInfo info = 1;
}
File diff suppressed because it is too large Load Diff
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.ClassDataWithSource import org.jetbrains.kotlin.serialization.ClassDataWithSource
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfoTable
class ClassDeserializer(private val components: DeserializationComponents) { class ClassDeserializer(private val components: DeserializationComponents) {
private val classes: (ClassKey) -> ClassDescriptor? = private val classes: (ClassKey) -> ClassDescriptor? =
@@ -58,7 +59,12 @@ class ClassDeserializer(private val components: DeserializationComponents) {
if (!fragment.hasTopLevelClass(classId.shortClassName)) return null if (!fragment.hasTopLevelClass(classId.shortClassName)) return null
} }
components.createContext(fragment, nameResolver, TypeTable(classProto.typeTable), containerSource = null) components.createContext(
fragment, nameResolver,
TypeTable(classProto.typeTable),
SinceKotlinInfoTable.create(classProto.sinceKotlinInfoTable),
containerSource = null
)
} }
return DeserializedClassDescriptor(outerContext, classProto, nameResolver, sourceElement) return DeserializedClassDescriptor(outerContext, classProto, nameResolver, sourceElement)
@@ -50,6 +50,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
proto, proto,
c.nameResolver, c.nameResolver,
c.typeTable, c.typeTable,
c.sinceKotlinInfoTable,
c.containerSource c.containerSource
) )
@@ -154,7 +155,8 @@ class MemberDeserializer(private val c: DeserializationContext) {
else Annotations.EMPTY else Annotations.EMPTY
val function = DeserializedSimpleFunctionDescriptor( val function = DeserializedSimpleFunctionDescriptor(
c.containingDeclaration, /* original = */ null, annotations, c.nameResolver.getName(proto.name), c.containingDeclaration, /* original = */ null, annotations, c.nameResolver.getName(proto.name),
Deserialization.memberKind(Flags.MEMBER_KIND.get(flags)), proto, c.nameResolver, c.typeTable, c.containerSource Deserialization.memberKind(Flags.MEMBER_KIND.get(flags)), proto, c.nameResolver, c.typeTable, c.sinceKotlinInfoTable,
c.containerSource
) )
val local = c.childContext(function, proto.typeParameterList) val local = c.childContext(function, proto.typeParameterList)
function.initialize( function.initialize(
@@ -181,7 +183,7 @@ class MemberDeserializer(private val c: DeserializationContext) {
val visibility = Deserialization.visibility(Flags.VISIBILITY.get(proto.flags)) val visibility = Deserialization.visibility(Flags.VISIBILITY.get(proto.flags))
val typeAlias = DeserializedTypeAliasDescriptor( val typeAlias = DeserializedTypeAliasDescriptor(
c.containingDeclaration, annotations, c.nameResolver.getName(proto.name), c.containingDeclaration, annotations, c.nameResolver.getName(proto.name),
visibility, proto, c.nameResolver, c.typeTable, c.containerSource visibility, proto, c.nameResolver, c.typeTable, c.sinceKotlinInfoTable, c.containerSource
) )
val local = c.childContext(typeAlias, proto.typeParameterList) val local = c.childContext(typeAlias, proto.typeParameterList)
@@ -202,7 +204,8 @@ class MemberDeserializer(private val c: DeserializationContext) {
val classDescriptor = c.containingDeclaration as ClassDescriptor val classDescriptor = c.containingDeclaration as ClassDescriptor
val descriptor = DeserializedClassConstructorDescriptor( val descriptor = DeserializedClassConstructorDescriptor(
classDescriptor, null, getAnnotations(proto, proto.flags, AnnotatedCallableKind.FUNCTION), classDescriptor, null, getAnnotations(proto, proto.flags, AnnotatedCallableKind.FUNCTION),
isPrimary, CallableMemberDescriptor.Kind.DECLARATION, proto, c.nameResolver, c.typeTable, c.containerSource isPrimary, CallableMemberDescriptor.Kind.DECLARATION, proto, c.nameResolver, c.typeTable, c.sinceKotlinInfoTable,
c.containerSource
) )
val local = c.childContext(descriptor, listOf()) val local = c.childContext(descriptor, listOf())
descriptor.initialize( descriptor.initialize(
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfoTable
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
class DeserializationComponents( class DeserializationComponents(
@@ -50,9 +51,10 @@ class DeserializationComponents(
descriptor: PackageFragmentDescriptor, descriptor: PackageFragmentDescriptor,
nameResolver: NameResolver, nameResolver: NameResolver,
typeTable: TypeTable, typeTable: TypeTable,
sinceKotlinInfoTable: SinceKotlinInfoTable,
containerSource: DeserializedContainerSource? containerSource: DeserializedContainerSource?
): DeserializationContext = ): DeserializationContext =
DeserializationContext(this, nameResolver, descriptor, typeTable, containerSource, DeserializationContext(this, nameResolver, descriptor, typeTable, sinceKotlinInfoTable, containerSource,
parentTypeDeserializer = null, typeParameters = listOf()) parentTypeDeserializer = null, typeParameters = listOf())
} }
@@ -62,6 +64,7 @@ class DeserializationContext(
val nameResolver: NameResolver, val nameResolver: NameResolver,
val containingDeclaration: DeclarationDescriptor, val containingDeclaration: DeclarationDescriptor,
val typeTable: TypeTable, val typeTable: TypeTable,
val sinceKotlinInfoTable: SinceKotlinInfoTable,
val containerSource: DeserializedContainerSource?, val containerSource: DeserializedContainerSource?,
parentTypeDeserializer: TypeDeserializer?, parentTypeDeserializer: TypeDeserializer?,
typeParameters: List<ProtoBuf.TypeParameter> typeParameters: List<ProtoBuf.TypeParameter>
@@ -79,7 +82,7 @@ class DeserializationContext(
nameResolver: NameResolver = this.nameResolver, nameResolver: NameResolver = this.nameResolver,
typeTable: TypeTable = this.typeTable typeTable: TypeTable = this.typeTable
) = DeserializationContext( ) = DeserializationContext(
components, nameResolver, descriptor, typeTable, this.containerSource, components, nameResolver, descriptor, typeTable, sinceKotlinInfoTable, this.containerSource,
parentTypeDeserializer = this.typeDeserializer, typeParameters = typeParameterProtos parentTypeDeserializer = this.typeDeserializer, typeParameters = typeParameterProtos
) )
} }
@@ -39,6 +39,11 @@ interface DeserializedMemberDescriptor : MemberDescriptor {
val typeTable: TypeTable val typeTable: TypeTable
val sinceKotlinInfoTable: SinceKotlinInfoTable
val sinceKotlinInfo: SinceKotlinInfo?
get() = SinceKotlinInfo.create(proto, nameResolver, sinceKotlinInfoTable)
// Information about the origin of this callable's container (class or package part on JVM) or null if there's no such information. // Information about the origin of this callable's container (class or package part on JVM) or null if there's no such information.
val containerSource: DeserializedContainerSource? val containerSource: DeserializedContainerSource?
} }
@@ -65,6 +70,7 @@ class DeserializedSimpleFunctionDescriptor(
override val proto: ProtoBuf.Function, override val proto: ProtoBuf.Function,
override val nameResolver: NameResolver, override val nameResolver: NameResolver,
override val typeTable: TypeTable, override val typeTable: TypeTable,
override val sinceKotlinInfoTable: SinceKotlinInfoTable,
override val containerSource: DeserializedContainerSource?, override val containerSource: DeserializedContainerSource?,
source: SourceElement? = null source: SourceElement? = null
) : DeserializedCallableMemberDescriptor, ) : DeserializedCallableMemberDescriptor,
@@ -82,7 +88,7 @@ class DeserializedSimpleFunctionDescriptor(
): FunctionDescriptorImpl { ): FunctionDescriptorImpl {
return DeserializedSimpleFunctionDescriptor( return DeserializedSimpleFunctionDescriptor(
newOwner, original as SimpleFunctionDescriptor?, annotations, newName ?: name, kind, newOwner, original as SimpleFunctionDescriptor?, annotations, newName ?: name, kind,
proto, nameResolver, typeTable, containerSource, source proto, nameResolver, typeTable, sinceKotlinInfoTable, containerSource, source
) )
} }
} }
@@ -102,6 +108,7 @@ class DeserializedPropertyDescriptor(
override val proto: ProtoBuf.Property, override val proto: ProtoBuf.Property,
override val nameResolver: NameResolver, override val nameResolver: NameResolver,
override val typeTable: TypeTable, override val typeTable: TypeTable,
override val sinceKotlinInfoTable: SinceKotlinInfoTable,
override val containerSource: DeserializedContainerSource? override val containerSource: DeserializedContainerSource?
) : DeserializedCallableMemberDescriptor, ) : DeserializedCallableMemberDescriptor,
PropertyDescriptorImpl(containingDeclaration, original, annotations, PropertyDescriptorImpl(containingDeclaration, original, annotations,
@@ -117,7 +124,7 @@ class DeserializedPropertyDescriptor(
): PropertyDescriptorImpl { ): PropertyDescriptorImpl {
return DeserializedPropertyDescriptor( return DeserializedPropertyDescriptor(
newOwner, original, annotations, newModality, newVisibility, isVar, name, kind, isLateInit, isConst, isExternal, newOwner, original, annotations, newModality, newVisibility, isVar, name, kind, isLateInit, isConst, isExternal,
proto, nameResolver, typeTable, containerSource proto, nameResolver, typeTable, sinceKotlinInfoTable, containerSource
) )
} }
@@ -133,6 +140,7 @@ class DeserializedClassConstructorDescriptor(
override val proto: ProtoBuf.Constructor, override val proto: ProtoBuf.Constructor,
override val nameResolver: NameResolver, override val nameResolver: NameResolver,
override val typeTable: TypeTable, override val typeTable: TypeTable,
override val sinceKotlinInfoTable: SinceKotlinInfoTable,
override val containerSource: DeserializedContainerSource?, override val containerSource: DeserializedContainerSource?,
source: SourceElement? = null source: SourceElement? = null
) : DeserializedCallableMemberDescriptor, ) : DeserializedCallableMemberDescriptor,
@@ -148,7 +156,7 @@ class DeserializedClassConstructorDescriptor(
): DeserializedClassConstructorDescriptor { ): DeserializedClassConstructorDescriptor {
return DeserializedClassConstructorDescriptor( return DeserializedClassConstructorDescriptor(
newOwner as ClassDescriptor, original as ConstructorDescriptor?, annotations, isPrimary, kind, newOwner as ClassDescriptor, original as ConstructorDescriptor?, annotations, isPrimary, kind,
proto, nameResolver, typeTable, containerSource, source proto, nameResolver, typeTable, sinceKotlinInfoTable, containerSource, source
) )
} }
@@ -169,6 +177,7 @@ class DeserializedTypeAliasDescriptor(
override val proto: ProtoBuf.TypeAlias, override val proto: ProtoBuf.TypeAlias,
override val nameResolver: NameResolver, override val nameResolver: NameResolver,
override val typeTable: TypeTable, override val typeTable: TypeTable,
override val sinceKotlinInfoTable: SinceKotlinInfoTable,
override val containerSource: DeserializedContainerSource? override val containerSource: DeserializedContainerSource?
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility), ) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility),
DeserializedMemberDescriptor { DeserializedMemberDescriptor {
@@ -198,7 +207,9 @@ class DeserializedTypeAliasDescriptor(
override fun substitute(substitutor: TypeSubstitutor): TypeAliasDescriptor { override fun substitute(substitutor: TypeSubstitutor): TypeAliasDescriptor {
if (substitutor.isEmpty) return this if (substitutor.isEmpty) return this
val substituted = DeserializedTypeAliasDescriptor(containingDeclaration, annotations, name, visibility, proto, nameResolver, typeTable, containerSource) val substituted = DeserializedTypeAliasDescriptor(
containingDeclaration, annotations, name, visibility, proto, nameResolver, typeTable, sinceKotlinInfoTable, containerSource
)
substituted.initialize(declaredTypeParameters, substituted.initialize(declaredTypeParameters,
substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType(), substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType(),
substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType()) substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType())
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.serialization.deserialization.descriptors
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -36,7 +35,8 @@ open class DeserializedPackageMemberScope(
components: DeserializationComponents, components: DeserializationComponents,
classNames: () -> Collection<Name> classNames: () -> Collection<Name>
) : DeserializedMemberScope( ) : DeserializedMemberScope(
components.createContext(packageDescriptor, nameResolver, TypeTable(proto.typeTable), containerSource), components.createContext(packageDescriptor, nameResolver, TypeTable(proto.typeTable),
SinceKotlinInfoTable.create(proto.sinceKotlinInfoTable), containerSource),
proto.functionList, proto.propertyList, proto.typeAliasList, classNames proto.functionList, proto.propertyList, proto.typeAliasList, classNames
) { ) {
private val packageFqName = packageDescriptor.fqName private val packageFqName = packageDescriptor.fqName
@@ -0,0 +1,107 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.serialization.deserialization.descriptors
import org.jetbrains.kotlin.protobuf.MessageLite
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
class SinceKotlinInfoTable private constructor(private val infos: List<ProtoBuf.SinceKotlinInfo>) {
operator fun get(id: Int): ProtoBuf.SinceKotlinInfo? = infos.getOrNull(id)
companion object {
val EMPTY = SinceKotlinInfoTable(emptyList())
fun create(table: ProtoBuf.SinceKotlinInfoTable): SinceKotlinInfoTable =
if (table.infoCount == 0) EMPTY else SinceKotlinInfoTable(table.infoList)
}
}
class SinceKotlinInfo(
val version: Version,
val level: DeprecationLevel,
val errorCode: Int?,
val message: String?
) {
class Version(val major: Int, val minor: Int, val patch: Int) {
fun asString(): String =
if (patch == 0) "$major.$minor" else "$major.$minor.$patch"
override fun toString(): String = asString()
companion object {
val DEFAULT = Version(1, 0, 0)
// Number of bits used for major, minor and patch components in "version" field
private const val MAJOR_BITS = 3
private const val MINOR_BITS = 4
private const val PATCH_BITS = 7
private const val MAJOR_MASK = (1 shl MAJOR_BITS) - 1
private const val MINOR_MASK = (1 shl MINOR_BITS) - 1
private const val PATCH_MASK = (1 shl PATCH_BITS) - 1
fun decode(version: Int?, versionFull: Int?): Version = when {
versionFull != null -> Version(
major = versionFull and 255,
minor = (versionFull shr 8) and 255,
patch = (versionFull shr 16) and 255
)
version != null -> Version(
major = version and MAJOR_MASK,
minor = (version shr MAJOR_BITS) and MINOR_MASK,
patch = (version shr (MAJOR_BITS + MINOR_BITS)) and PATCH_MASK
)
else -> Version.DEFAULT
}
}
}
override fun toString(): String =
"since $version $level" + (if (errorCode != null) " error $errorCode" else "") + (if (message != null) ": $message" else "")
companion object {
fun create(proto: MessageLite, nameResolver: NameResolver, table: SinceKotlinInfoTable): SinceKotlinInfo? {
val id = when (proto) {
is ProtoBuf.Class -> if (proto.hasSinceKotlinInfo()) proto.sinceKotlinInfo else return null
is ProtoBuf.Constructor -> if (proto.hasSinceKotlinInfo()) proto.sinceKotlinInfo else return null
is ProtoBuf.Function -> if (proto.hasSinceKotlinInfo()) proto.sinceKotlinInfo else return null
is ProtoBuf.Property -> if (proto.hasSinceKotlinInfo()) proto.sinceKotlinInfo else return null
is ProtoBuf.TypeAlias -> if (proto.hasSinceKotlinInfo()) proto.sinceKotlinInfo else return null
else -> throw IllegalStateException("Unexpected declaration: ${proto.javaClass}")
}
val info = table[id] ?: return null
val version = Version.decode(
if (info.hasVersion()) info.version else null,
if (info.hasVersionFull()) info.versionFull else null
)
val level = when (info.level!!) {
ProtoBuf.SinceKotlinInfo.Level.WARNING -> DeprecationLevel.WARNING
ProtoBuf.SinceKotlinInfo.Level.ERROR -> DeprecationLevel.ERROR
ProtoBuf.SinceKotlinInfo.Level.HIDDEN -> DeprecationLevel.HIDDEN
}
val errorCode = if (info.hasErrorCode()) info.errorCode else null
val message = if (info.hasMessage()) nameResolver.getString(info.message) else null
return SinceKotlinInfo(version, level, errorCode, message)
}
}
}
@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") // kotlin.Metadata @file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
package kotlin.reflect.jvm package kotlin.reflect.jvm
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
import org.jetbrains.kotlin.serialization.deserialization.TypeTable import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.serialization.deserialization.descriptors.SinceKotlinInfoTable
import org.jetbrains.kotlin.serialization.jvm.BitEncoding import org.jetbrains.kotlin.serialization.jvm.BitEncoding
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
@@ -45,7 +46,7 @@ fun <R> Function<R>.reflect(): KFunction<R>? {
val proto = ProtoBuf.Function.parseFrom(input, JvmProtoBufUtil.EXTENSION_REGISTRY) val proto = ProtoBuf.Function.parseFrom(input, JvmProtoBufUtil.EXTENSION_REGISTRY)
val moduleData = javaClass.getOrCreateModule() val moduleData = javaClass.getOrCreateModule()
val context = DeserializationContext( val context = DeserializationContext(
moduleData.deserialization, nameResolver, moduleData.module, TypeTable(proto.typeTable), moduleData.deserialization, nameResolver, moduleData.module, TypeTable(proto.typeTable), SinceKotlinInfoTable.EMPTY,
containerSource = null, parentTypeDeserializer = null, typeParameters = proto.typeParameterList containerSource = null, parentTypeDeserializer = null, typeParameters = proto.typeParameterList
) )
val descriptor = MemberDeserializer(context).loadFunction(proto) val descriptor = MemberDeserializer(context).loadFunction(proto)