Update syntax to Kotlin 1.6, highlight label in 'this@Foo'

This commit is contained in:
Alexander Udalov
2021-11-07 03:53:35 +01:00
parent 1ce19a8d73
commit c126f6dc72
2 changed files with 27 additions and 23 deletions

View File

@@ -1,227 +0,0 @@
#!/usr/bin/env kotlin
/**
* This script loads metadata of all public classes and type aliases from kotlin-stdlib and dumps their names
* to stdout, ready to be used in the Vim syntax file.
*
* To run locally, change stdlib paths in STDLIB and STDLIB_COMMON variables below. You can download the latter
* from Maven Central, or build it in the Kotlin project itself with `./gradlew dist`.
*/
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0")
@file:DependsOn("org.ow2.asm:asm:8.0.1")
import kotlinx.metadata.Flag
import kotlinx.metadata.KmClass
import kotlinx.metadata.internal.metadata.ProtoBuf
import kotlinx.metadata.internal.metadata.builtins.BuiltInsBinaryVersion
import kotlinx.metadata.internal.metadata.builtins.BuiltInsProtoBuf
import kotlinx.metadata.internal.metadata.deserialization.Flags
import kotlinx.metadata.internal.metadata.deserialization.NameResolver
import kotlinx.metadata.internal.metadata.deserialization.NameResolverImpl
import kotlinx.metadata.internal.protobuf.ExtensionRegistryLite
import kotlinx.metadata.isLocal
import kotlinx.metadata.jvm.KotlinClassHeader
import kotlinx.metadata.jvm.KotlinClassMetadata
import org.objectweb.asm.AnnotationVisitor
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassReader.*
import org.objectweb.asm.ClassVisitor
import org.objectweb.asm.Opcodes
import java.io.File
import java.io.InputStream
import java.util.zip.ZipFile
val STDLIB = File(System.getProperty("user.home") + "/kotlin/dist/kotlinc/lib/kotlin-stdlib.jar")
val STDLIB_COMMON = File(System.getProperty("user.home") + "/kotlin/libraries/stdlib/common/build/libs/kotlin-stdlib-common-1.5.255-SNAPSHOT.jar")
val DEBUG = false
val PREFIX = "syn keyword ktType"
val CUTOFF = 180
fun extractSimpleNameFromClass(inputStream: InputStream): String? {
val reader = ClassReader(inputStream)
var kind: Int? = null
var metadataVersion: IntArray? = null
var bytecodeVersion: IntArray? = null
var data1: Array<String>? = null
var data2: Array<String>? = null
var extraString: String? = null
var packageName: String? = null
var extraInt: Int? = null
reader.accept(object : ClassVisitor(Opcodes.ASM8) {
override fun visitAnnotation(descriptor: String?, visible: Boolean): AnnotationVisitor? {
if (descriptor != "Lkotlin/Metadata;") return null
return object : AnnotationVisitor(Opcodes.ASM8) {
override fun visit(name: String?, value: Any?) {
when (name) {
"k" -> kind = value as Int
"mv" -> metadataVersion = value as IntArray
"bv" -> bytecodeVersion = value as IntArray
"xs" -> extraString = value as String
"pn" -> packageName = value as String
"xi" -> extraInt = value as Int
}
}
override fun visitArray(name: String?): AnnotationVisitor =
object : AnnotationVisitor(Opcodes.ASM8) {
val strings = mutableListOf<String>()
override fun visit(empty: String?, value: Any?) {
strings += value as String
}
override fun visitEnd() {
when (name) {
"d1" -> data1 = strings.toTypedArray()
"d2" -> data2 = strings.toTypedArray()
}
}
}
}
}
}, SKIP_CODE or SKIP_DEBUG or SKIP_FRAMES)
if (kind == null) return null
val header = KotlinClassHeader(kind, metadataVersion, bytecodeVersion, data1, data2, extraString, packageName, extraInt)
when (val metadata = KotlinClassMetadata.read(header)) {
is KotlinClassMetadata.Class -> {
val klass = metadata.toKmClass()
if (isPublicAPI(klass)) {
val simpleName = klass.name.simpleName
if (simpleName != "Companion") {
if (DEBUG) {
println("class ${klass.name} -> $simpleName")
}
return simpleName
}
}
}
}
return null
}
val String.simpleName: String
get() = substringAfterLast('/').substringAfterLast('.')
fun extractSimpleNamesFromBuiltins(inputStream: InputStream, packageName: String): List<String> {
val proto = inputStream.use { stream ->
val version = BuiltInsBinaryVersion.readFrom(stream)
require(version.isCompatible())
ProtoBuf.PackageFragment.parseFrom(
stream,
ExtensionRegistryLite.newInstance().apply(BuiltInsProtoBuf::registerAllExtensions)
)
}
val strings = NameResolverImpl(proto.strings, proto.qualifiedNames)
val classNames = proto.class_List
.filter { isPublicAPI(it, strings) }
.map {
val name = strings.getQualifiedClassName(it.fqName)
if (DEBUG) {
println("builtin class $name -> ${name.simpleName}")
}
name.simpleName
}
val typeAliasNames = proto.`package`.typeAliasList
.mapNotNull {
val simpleName = strings.getString(it.name)
val fullName = "$packageName/$simpleName"
if (isPublicAPI(it, fullName, strings)) {
if (DEBUG) {
println("builtin typealias $fullName -> $simpleName")
}
simpleName
} else null
}
// TODO: fix typealias loading and avoid kotlin-stdlib-common
require(typeAliasNames.isEmpty())
return classNames + typeAliasNames
}
fun isPublicAPI(klass: KmClass): Boolean {
val name = klass.name
return !name.isLocal &&
isPublicAPIName(name) &&
(Flag.IS_PUBLIC(klass.flags) || Flag.IS_PROTECTED(klass.flags))
}
fun isPublicAPI(klass: ProtoBuf.Class, strings: NameResolver): Boolean =
!strings.isLocalClassName(klass.fqName) &&
isPublicAPIName(strings.getQualifiedClassName(klass.fqName)) &&
Flags.VISIBILITY.get(klass.flags).let { visibility ->
visibility == ProtoBuf.Visibility.PUBLIC || visibility == ProtoBuf.Visibility.PROTECTED
}
fun isPublicAPI(typeAlias: ProtoBuf.TypeAlias, fullName: String, strings: NameResolver): Boolean =
isPublicAPIName(fullName) &&
Flags.VISIBILITY.get(typeAlias.flags).let { visibility ->
visibility == ProtoBuf.Visibility.PUBLIC || visibility == ProtoBuf.Visibility.PROTECTED
} &&
// This is kind of a hack, but we don't want deprecated stuff to be used anyway.
// This is only done for type aliases though, since for classes it's more difficult to load annotations.
typeAlias.annotationList.none {
strings.getQualifiedClassName(it.id) == "kotlin/Deprecated"
}
// These names are too common to be highlighted only on the basis that there are such classes in kotlin-stdlib.
val TOO_COMMON_NAMES = setOf("Companion", "Default")
fun isPublicAPIName(name: String): Boolean =
"/internal/" !in name && name.simpleName !in TOO_COMMON_NAMES
fun collectClassNames(file: File): List<String> {
val classNames = mutableListOf<String>()
ZipFile(file).use { zipFile ->
for (entry in zipFile.entries()) {
when {
entry.name.endsWith(".class") -> {
extractSimpleNameFromClass(zipFile.getInputStream(entry))?.let { simpleName ->
classNames += simpleName
}
}
entry.name.endsWith(".kotlin_builtins") || entry.name.endsWith(".kotlin_metadata") -> {
classNames += extractSimpleNamesFromBuiltins(
zipFile.getInputStream(entry),
entry.name.substringBeforeLast('/')
)
}
}
}
}
return classNames
}
fun outputClassNames(unsortedNames: List<String>) {
val names = HashSet(unsortedNames).sorted()
var current = StringBuilder(PREFIX)
for (name in names) {
if (current.length + 1 + name.length > CUTOFF) {
println(current)
current = StringBuilder(PREFIX)
}
current.append(" ").append(name)
}
if (current.length > PREFIX.length) {
println(current)
}
}
fun main() {
val names = collectClassNames(STDLIB) + collectClassNames(STDLIB_COMMON)
outputClassNames(names)
}
main()

View File

@@ -17,11 +17,12 @@ syn keyword ktException try catch finally throw
syn keyword ktInclude import package
" The following is generated by generate-stdlib-class-names.main.kts
" Generated stdlib class names {{{
" The following is generated by https://github.com/udalov/kotlin-vim/blob/master/extra/generate-stdlib-class-names.main.kts
syn keyword ktType AbstractCollection AbstractCoroutineContextElement AbstractCoroutineContextKey AbstractDoubleTimeSource AbstractIterator AbstractList AbstractLongTimeSource
syn keyword ktType AbstractMap AbstractMutableCollection AbstractMutableList AbstractMutableMap AbstractMutableSet AbstractSet AccessDeniedException Accessor Annotation
syn keyword ktType AnnotationRetention AnnotationTarget Any Appendable ArithmeticException Array ArrayDeque ArrayList AssertionError Boolean BooleanArray BooleanIterator
syn keyword ktType BuilderInference Byte ByteArray ByteIterator CallsInPlace CancellationException Char CharArray CharCategory CharDirectionality CharIterator CharProgression
syn keyword ktType BuilderInference Byte ByteArray ByteIterator CName CallsInPlace CancellationException Char CharArray CharCategory CharDirectionality CharIterator CharProgression
syn keyword ktType CharRange CharSequence CharacterCodingException Charsets ClassCastException Cloneable ClosedFloatingPointRange ClosedRange Collection Comparable Comparator
syn keyword ktType ConcurrentModificationException ConditionalEffect Continuation ContinuationInterceptor ContractBuilder CoroutineContext DeepRecursiveFunction DeepRecursiveScope
syn keyword ktType Delegates Deprecated DeprecatedSinceKotlin DeprecationLevel Destructured Double DoubleArray DoubleIterator DslMarker Duration DurationUnit Effect Element
@@ -30,19 +31,20 @@ syn keyword ktType ExperimentalTime ExperimentalTypeInference ExperimentalUnsign
syn keyword ktType FileWalkDirection Float FloatArray FloatIterator Function Function0 Function1 Function10 Function11 Function12 Function13 Function14 Function15 Function16
syn keyword ktType Function17 Function18 Function19 Function2 Function20 Function21 Function22 Function3 Function4 Function5 Function6 Function7 Function8 Function9 FunctionN
syn keyword ktType Getter Grouping HashMap HashSet IllegalArgumentException IllegalStateException IndexOutOfBoundsException IndexedValue Int IntArray IntIterator IntProgression
syn keyword ktType IntRange InvocationKind Iterable Iterator JsExport JsName JvmDefault JvmDefaultWithoutCompatibility JvmField JvmInline JvmMultifileClass JvmName JvmOverloads
syn keyword ktType JvmRecord JvmStatic JvmSuppressWildcards JvmSynthetic JvmWildcard KAnnotatedElement KCallable KClass KClassifier KDeclarationContainer KFunction KMutableProperty
syn keyword ktType KMutableProperty0 KMutableProperty1 KMutableProperty2 KParameter KProperty KProperty0 KProperty1 KProperty2 KType KTypeParameter KTypeProjection KVariance
syn keyword ktType KVisibility Key Kind KotlinNullPointerException KotlinReflectionNotSupportedError KotlinVersion Lazy LazyThreadSafetyMode Level LinkedHashMap LinkedHashSet List
syn keyword ktType ListIterator Long LongArray LongIterator LongProgression LongRange Map MatchGroup MatchGroupCollection MatchNamedGroupCollection MatchResult Metadata Monotonic
syn keyword ktType MustBeDocumented MutableCollection MutableEntry MutableIterable MutableIterator MutableList MutableListIterator MutableMap MutableSet NoSuchElementException
syn keyword ktType NoSuchFileException NoWhenBranchMatchedException NotImplementedError Nothing NullPointerException Number NumberFormatException ObservableProperty OnErrorAction
syn keyword ktType OptIn OptionalExpectation OverloadResolutionByLambdaReturnType Pair ParameterName PropertyDelegateProvider PublishedApi PurelyImplements Random RandomAccess
syn keyword ktType ReadOnlyProperty ReadWriteProperty Regex RegexOption Repeatable ReplaceWith RequiresOptIn RestrictsSuspension Result Retention Returns ReturnsNotNull
syn keyword ktType RuntimeException Sequence SequenceScope Set Setter SharedImmutable Short ShortArray ShortIterator SimpleEffect SinceKotlin Strictfp String StringBuilder Suppress
syn keyword ktType Synchronized Target TestTimeSource ThreadLocal Throwable Throws TimeMark TimeSource TimedValue Transient Triple TypeCastException Typography UByte UByteArray
syn keyword ktType UByteIterator UInt UIntArray UIntIterator UIntProgression UIntRange ULong ULongArray ULongIterator ULongProgression ULongRange UShort UShortArray UShortIterator
syn keyword ktType UninitializedPropertyAccessException Unit UnsafeVariance UnsupportedOperationException UseExperimental Volatile
syn keyword ktType IntRange InvocationKind Iterable Iterator JsEagerInitialization JsExport JsName JvmDefault JvmDefaultWithoutCompatibility JvmField JvmInline JvmMultifileClass
syn keyword ktType JvmName JvmOverloads JvmRecord JvmStatic JvmSuppressWildcards JvmSynthetic JvmWildcard KAnnotatedElement KCallable KClass KClassifier KDeclarationContainer
syn keyword ktType KFunction KMutableProperty KMutableProperty0 KMutableProperty1 KMutableProperty2 KParameter KProperty KProperty0 KProperty1 KProperty2 KType KTypeParameter
syn keyword ktType KTypeProjection KVariance KVisibility Key Kind KotlinNullPointerException KotlinReflectionNotSupportedError KotlinVersion Lazy LazyThreadSafetyMode Level
syn keyword ktType LinkedHashMap LinkedHashSet List ListIterator Long LongArray LongIterator LongProgression LongRange Map MatchGroup MatchGroupCollection MatchNamedGroupCollection
syn keyword ktType MatchResult Metadata Monotonic MustBeDocumented MutableCollection MutableEntry MutableIterable MutableIterator MutableList MutableListIterator MutableMap
syn keyword ktType MutableSet NoSuchElementException NoSuchFileException NoWhenBranchMatchedException NotImplementedError Nothing NullPointerException Number NumberFormatException
syn keyword ktType ObservableProperty OnErrorAction OptIn OptionalExpectation OverloadResolutionByLambdaReturnType Pair ParameterName PropertyDelegateProvider PublishedApi
syn keyword ktType PurelyImplements Random RandomAccess ReadOnlyProperty ReadWriteProperty Regex RegexOption Repeatable ReplaceWith RequiresOptIn RestrictsSuspension Result
syn keyword ktType Retention Returns ReturnsNotNull RuntimeException Sequence SequenceScope Set Setter SharedImmutable Short ShortArray ShortIterator SimpleEffect SinceKotlin
syn keyword ktType Strictfp String StringBuilder Suppress Synchronized Target TestTimeSource ThreadLocal Throwable Throws TimeMark TimeSource TimedValue Transient Triple
syn keyword ktType TypeCastException Typography UByte UByteArray UByteIterator UInt UIntArray UIntIterator UIntProgression UIntRange ULong ULongArray ULongIterator ULongProgression
syn keyword ktType ULongRange UShort UShortArray UShortIterator UninitializedPropertyAccessException Unit UnsafeVariance UnsupportedOperationException UseExperimental Volatile
" }}}
syn keyword ktModifier annotation companion enum inner abstract final open override sealed vararg dynamic expect actual suspend
syn keyword ktStructure class object interface typealias fun val var constructor init
@@ -81,9 +83,9 @@ syn match ktCharacter "\v'[^']*'" contains=ktSpecialChar,ktSpecialCharError
syn match ktCharacter "\v'\\''" contains=ktSpecialChar
syn match ktCharacter "\v'[^\\]'"
" TODO: highlight label in 'this@Foo'
syn match ktAnnotation "\v(\w)@<!\@[[:alnum:]_.]*(:[[:alnum:]_.]*)?"
syn match ktLabel "\v\w+\@"
syn match ktLabel "\v(\w)@<=\@\w+"
syn match ktSimpleInterpolation "\v\$\h\w*" contained
syn region ktComplexInterpolation matchgroup=ktComplexInterpolationBrace start="\v\$\{" end="\v\}" contains=ALLBUT,ktSimpleInterpolation,ktTodo,ktSpecialCharError,ktSpecialChar,ktDocTag,ktDocTagParam
@@ -147,3 +149,5 @@ hi def link ktExclExcl Special
hi def link ktArrow Structure
let b:current_syntax = 'kotlin'
" vim:foldmethod=marker