/*
 * Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

package kotlin.js

import kotlin.contracts.contract

internal annotation class DoNotIntrinsify

internal fun String.charCodeAt(index: Int): Char = asDynamic().charCodeAt(index)

@PublishedApi
@DoNotIntrinsify
@Suppress("UNUSED") // Usages are generated by the compiler
internal fun charSequenceGet(a: CharSequence, index: Int): Char {
    return if (isString(a)) {
        a.charCodeAt(index)
    } else {
        a[index]
    }
}

@PublishedApi
@DoNotIntrinsify
@Suppress("UNUSED") // Usages are generated by the compiler
internal fun charSequenceLength(a: CharSequence): Int {
    return if (isString(a)) {
        a.asDynamic().length.unsafeCast<Int>()
    } else {
        a.length
    }
}

@PublishedApi
@DoNotIntrinsify
@Suppress("UNUSED") // Usages are generated by the compiler
internal fun charSequenceSubSequence(a: CharSequence, startIndex: Int, endIndex: Int): CharSequence {
    return if (isString(a)) {
        a.substring(startIndex, endIndex)
    } else {
        a.subSequence(startIndex, endIndex)
    }
}

// Keeping this function as separate non-inline to intrinsify `is` operator
internal fun isString(a: CharSequence): Boolean {
    contract { returns(true) implies (a is String) }
    return a is String
}
