mirror of
https://github.com/udalov/kotlin-vim.git
synced 2025-12-22 12:13:51 +01:00
Update syntax to Kotlin 1.6, highlight label in 'this@Foo'
This commit is contained in:
@@ -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()
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user