Deprecate `SendChannel.isFull` and `ReceiveChannel.isEmpty` properties

Fixes #1053
diff --git a/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt b/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt
index 0835243..38f7c3b 100644
--- a/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt
+++ b/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt
@@ -167,7 +167,8 @@
     // ------ SendChannel ------
 
     public final override val isClosedForSend: Boolean get() = closedForSend != null
-    public final override val isFull: Boolean get() = queue.nextNode !is ReceiveOrClosed<*> && isBufferFull
+    public final override val isFull: Boolean get() = full
+    private val full: Boolean get() = queue.nextNode !is ReceiveOrClosed<*> && isBufferFull // TODO rename to `isFull`
 
     public final override suspend fun send(element: E) {
         // fast path -- try offer non-blocking
@@ -402,7 +403,7 @@
     private fun <R> registerSelectSend(select: SelectInstance<R>, element: E, block: suspend (SendChannel<E>) -> R) {
         while (true) {
             if (select.isSelected) return
-            if (isFull) {
+            if (full) {
                 val enqueueOp = TryEnqueueSendDesc(element, select, block)
                 val enqueueResult = select.performAtomicIfNotSelected(enqueueOp) ?: return
                 when {
@@ -561,7 +562,8 @@
     // ------ ReceiveChannel ------
 
     public final override val isClosedForReceive: Boolean get() = closedForReceive != null && isBufferEmpty
-    public final override val isEmpty: Boolean get() = queue.nextNode !is Send && isBufferEmpty
+    public final override val isEmpty: Boolean get() = empty
+    private val empty: Boolean get() = queue.nextNode !is Send && isBufferEmpty // TODO rename to `isEmpty`
 
     @Suppress("UNCHECKED_CAST")
     public final override suspend fun receive(): E {
@@ -748,7 +750,7 @@
     private fun <R> registerSelectReceive(select: SelectInstance<R>, block: suspend (E) -> R) {
         while (true) {
             if (select.isSelected) return
-            if (isEmpty) {
+            if (empty) {
                 val enqueueOp = TryEnqueueReceiveDesc(select, block as (suspend (E?) -> R), nullOnClose = false)
                 val enqueueResult = select.performAtomicIfNotSelected(enqueueOp) ?: return
                 when {
@@ -782,7 +784,7 @@
     private fun <R> registerSelectReceiveOrNull(select: SelectInstance<R>, block: suspend (E?) -> R) {
         while (true) {
             if (select.isSelected) return
-            if (isEmpty) {
+            if (empty) {
                 val enqueueOp = TryEnqueueReceiveDesc(select, block, nullOnClose = true)
                 val enqueueResult = select.performAtomicIfNotSelected(enqueueOp) ?: return
                 when {
diff --git a/kotlinx-coroutines-core/common/src/channels/Channel.kt b/kotlinx-coroutines-core/common/src/channels/Channel.kt
index 351bd49..286196d 100644
--- a/kotlinx-coroutines-core/common/src/channels/Channel.kt
+++ b/kotlinx-coroutines-core/common/src/channels/Channel.kt
@@ -30,14 +30,15 @@
      * Returns `true` if the channel is full (out of capacity) and the [send] attempt will suspend.
      * This function returns `false` for [isClosedForSend] channel.
      *
-     * **Note: This is an experimental api.** This property may change its semantics and/or name in the future.
+     * @suppress **Will be removed in next releases, no replacement.**
      */
     @ExperimentalCoroutinesApi
+    @Deprecated(level = DeprecationLevel.ERROR, message = "Will be removed in next releases without replacement")
     public val isFull: Boolean
 
     /**
-     * Adds [element] into to this channel, suspending the caller while this channel [isFull],
-     * or throws exception if the channel [isClosedForSend] (see [close] for details).
+     * Adds [element] into to this channel, suspending the caller while the buffer of this channel is full
+     * or if it does not exist, or throws exception if the channel [isClosedForSend] (see [close] for details).
      *
      * Note, that closing a channel _after_ this function had suspended does not cause this suspended send invocation
      * to abort, because closing a channel is conceptually like sending a special "close token" over this channel.
@@ -151,13 +152,14 @@
      * Returns `true` if the channel is empty (contains no elements) and the [receive] attempt will suspend.
      * This function returns `false` for [isClosedForReceive] channel.
      *
-     * **Note: This is an experimental api.** This property may change its semantics and/or name in the future.
+     * @suppress **Will be removed in next releases, no replacement.**
      */
     @ExperimentalCoroutinesApi
+    @Deprecated(level = DeprecationLevel.ERROR, message = "Will be removed in next releases without replacement")
     public val isEmpty: Boolean
 
     /**
-     * Retrieves and removes the element from this channel suspending the caller while this channel [isEmpty]
+     * Retrieves and removes the element from this channel suspending the caller while this channel is empty,
      * or throws [ClosedReceiveChannelException] if the channel [isClosedForReceive].
      * If the channel was closed because of the exception, it is called a _failed_ channel and this function
      * throws the original [close][SendChannel.close] cause exception.
@@ -188,7 +190,7 @@
     public val onReceive: SelectClause1<E>
 
     /**
-     * Retrieves and removes the element from this channel suspending the caller while this channel [isEmpty]
+     * Retrieves and removes the element from this channel suspending the caller while this channel is empty,
      * or returns `null` if the channel is [closed][isClosedForReceive] without cause
      * or throws the original [close][SendChannel.close] cause exception if the channel has _failed_.
      *
@@ -227,7 +229,7 @@
     public val onReceiveOrNull: SelectClause1<E?>
 
     /**
-     * Retrieves and removes the element from this channel, or returns `null` if this channel [isEmpty]
+     * Retrieves and removes the element from this channel, or returns `null` if this channel is empty
      * or is [isClosedForReceive] without cause.
      * It throws the original [close][SendChannel.close] cause exception if the channel has _failed_.
      */
@@ -273,9 +275,8 @@
  */
 public interface ChannelIterator<out E> {
     /**
-     * Returns `true` if the channel has more elements suspending the caller while this channel
-     * [isEmpty][ReceiveChannel.isEmpty] or returns `false` if the channel
-     * [isClosedForReceive][ReceiveChannel.isClosedForReceive] without cause.
+     * Returns `true` if the channel has more elements, suspending the caller while this channel is empty,
+     * or returns `false` if the channel [isClosedForReceive][ReceiveChannel.isClosedForReceive] without cause.
      * It throws the original [close][SendChannel.close] cause exception if the channel has _failed_.
      *
      * This function retrieves and removes the element from this channel for the subsequent invocation
@@ -297,7 +298,7 @@
 
     /**
      * Retrieves and removes the element from this channel suspending the caller while this channel
-     * [isEmpty][ReceiveChannel.isEmpty] or throws [ClosedReceiveChannelException] if the channel
+     * is empty or throws [ClosedReceiveChannelException] if the channel
      * [isClosedForReceive][ReceiveChannel.isClosedForReceive] without cause.
      * It throws the original [close][SendChannel.close] cause exception if the channel has _failed_.
      *
diff --git a/kotlinx-coroutines-core/common/test/channels/ArrayChannelTest.kt b/kotlinx-coroutines-core/common/test/channels/ArrayChannelTest.kt
index 56a1c5a..308f8f3 100644
--- a/kotlinx-coroutines-core/common/test/channels/ArrayChannelTest.kt
+++ b/kotlinx-coroutines-core/common/test/channels/ArrayChannelTest.kt
@@ -11,12 +11,10 @@
     @Test
     fun testSimple() = runTest {
         val q = Channel<Int>(1)
-        check(q.isEmpty && !q.isFull)
         expect(1)
         val sender = launch {
             expect(4)
             q.send(1) // success -- buffered
-            check(!q.isEmpty && q.isFull)
             expect(5)
             q.send(2) // suspends (buffer full)
             expect(9)
@@ -25,7 +23,6 @@
         val receiver = launch {
             expect(6)
             check(q.receive() == 1) // does not suspend -- took from buffer
-            check(!q.isEmpty && q.isFull) // waiting sender's element moved to buffer
             expect(7)
             check(q.receive() == 2) // does not suspend (takes from sender)
             expect(8)
@@ -33,21 +30,20 @@
         expect(3)
         sender.join()
         receiver.join()
-        check(q.isEmpty && !q.isFull)
         finish(10)
     }
 
     @Test
     fun testClosedBufferedReceiveOrNull() = runTest {
         val q = Channel<Int>(1)
-        check(q.isEmpty && !q.isFull && !q.isClosedForSend && !q.isClosedForReceive)
+        check(!q.isClosedForSend && !q.isClosedForReceive)
         expect(1)
         launch {
             expect(5)
-            check(!q.isEmpty && !q.isFull && q.isClosedForSend && !q.isClosedForReceive)
+            check(q.isClosedForSend && !q.isClosedForReceive)
             assertEquals(42, q.receiveOrNull())
             expect(6)
-            check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
+            check(q.isClosedForSend && q.isClosedForReceive)
             assertEquals(null, q.receiveOrNull())
             expect(7)
         }
@@ -56,9 +52,9 @@
         expect(3)
         q.close() // goes on
         expect(4)
-        check(!q.isEmpty && !q.isFull && q.isClosedForSend && !q.isClosedForReceive)
+        check(q.isClosedForSend && !q.isClosedForReceive)
         yield()
-        check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
+        check(q.isClosedForSend && q.isClosedForReceive)
         finish(8)
     }
 
diff --git a/kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt b/kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt
index 60bccef..fafda0d 100644
--- a/kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt
+++ b/kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt
@@ -11,7 +11,6 @@
     @Test
     fun testSimple() = runTest {
         val q = Channel<Int>(Channel.RENDEZVOUS)
-        check(q.isEmpty && q.isFull)
         expect(1)
         val sender = launch {
             expect(4)
@@ -31,14 +30,13 @@
         expect(3)
         sender.join()
         receiver.join()
-        check(q.isEmpty && q.isFull)
         finish(10)
     }
 
     @Test
     fun testClosedReceiveOrNull() = runTest {
         val q = Channel<Int>(Channel.RENDEZVOUS)
-        check(q.isEmpty && q.isFull && !q.isClosedForSend && !q.isClosedForReceive)
+        check(!q.isClosedForSend && !q.isClosedForReceive)
         expect(1)
         launch {
             expect(3)
@@ -51,9 +49,9 @@
         q.send(42)
         expect(5)
         q.close()
-        check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
+        check(q.isClosedForSend && q.isClosedForReceive)
         yield()
-        check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive)
+        check(q.isClosedForSend && q.isClosedForReceive)
         finish(7)
     }
 
diff --git a/kotlinx-coroutines-core/common/test/channels/TestChannelKind.kt b/kotlinx-coroutines-core/common/test/channels/TestChannelKind.kt
index 465699e..6e1ee2b 100644
--- a/kotlinx-coroutines-core/common/test/channels/TestChannelKind.kt
+++ b/kotlinx-coroutines-core/common/test/channels/TestChannelKind.kt
@@ -54,6 +54,7 @@
     val sub = broadcast.openSubscription()
 
     override val isClosedForReceive: Boolean get() = sub.isClosedForReceive
+    @Suppress("DEPRECATION_ERROR")
     override val isEmpty: Boolean get() = sub.isEmpty
 
     override suspend fun receive(): E = sub.receive()