Skip to content

Commit

Permalink
ClassValueCompat to support systems without java.lang.ClassValue
Browse files Browse the repository at this point in the history
  • Loading branch information
nwk37011 committed Sep 7, 2021
1 parent 90ca82a commit e18202b
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/library/scala/reflect/ClassTag.scala
Expand Up @@ -17,6 +17,7 @@ import java.lang.{Class => jClass}
import java.lang.ref.{WeakReference => jWeakReference}

import scala.annotation.{implicitNotFound, nowarn}
import scala.runtime.ClassValueCompat

/**
*
Expand Down Expand Up @@ -116,7 +117,7 @@ object ClassTag {
val Null : ClassTag[scala.Null] = Manifest.Null

private val cacheDisabled = java.lang.Boolean.getBoolean("scala.reflect.classtag.cache.disable")
private[this] object cache extends ClassValue[jWeakReference[ClassTag[_]]] {
private[this] object cache extends ClassValueCompat[jWeakReference[ClassTag[_]]] {
override def computeValue(runtimeClass: jClass[_]): jWeakReference[ClassTag[_]] =
new jWeakReference(computeTag(runtimeClass))

Expand Down
66 changes: 66 additions & 0 deletions src/library/scala/runtime/ClassValueCompat.java
@@ -0,0 +1,66 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.runtime;

public abstract class ClassValueCompat<T> {

private static final boolean classValueAvailable = checkClassValueAvailability();

private static boolean checkClassValueAvailability() {
try {
Class.forName("java.lang.ClassValue", false, ClassValueCompat.class.getClassLoader());
return true;
} catch (ClassNotFoundException e) {
return false;
}
}

private final ClassValueInterface<T> instance;

protected ClassValueCompat() {
instance = classValueAvailable ? new JavaClassValue() : new FallbackClassValue();
}

private class JavaClassValue extends ClassValue<T> implements ClassValueInterface<T> {
@Override
protected T computeValue(Class<?> aClass) {
return ClassValueCompat.this.computeValue(aClass);
}
}

private class FallbackClassValue implements ClassValueInterface<T> {
@Override
public T get(Class<?> type) {
return ClassValueCompat.this.computeValue(type);
}

@Override
public void remove(Class<?> type) {}
}

protected abstract T computeValue(Class<?> type);

public T get(Class<?> type) {
return instance.get(type);
}

public void remove(Class<?> type) {
instance.remove(type);
}

public interface ClassValueInterface<T> {
T get(Class<?> param1Class);

void remove(Class<?> param1Class);
}
}
2 changes: 1 addition & 1 deletion src/library/scala/runtime/ModuleSerializationProxy.java
Expand Up @@ -22,7 +22,7 @@
public final class ModuleSerializationProxy implements Serializable {
private static final long serialVersionUID = 1L;
private final Class<?> moduleClass;
private static final ClassValue<Object> instances = new ClassValue<Object>() {
private static final ClassValueCompat<Object> instances = new ClassValueCompat<Object>() {
@Override
@SuppressWarnings("removal") // JDK 17 deprecates AccessController
protected Object computeValue(Class<?> type) {
Expand Down
3 changes: 2 additions & 1 deletion src/reflect/scala/reflect/macros/Attachments.scala
Expand Up @@ -15,6 +15,7 @@ package reflect
package macros

import reflect.internal.util.Position
import scala.runtime.ClassValueCompat

/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
Expand Down Expand Up @@ -109,7 +110,7 @@ abstract class Attachments { self =>
}

private object Attachments {
private val matchesTagCache = new ClassValue[Function1[Any, Boolean]] {
private val matchesTagCache = new ClassValueCompat[Function1[Any, Boolean]] {
override def computeValue(cls: Class[_]): Function[Any, Boolean] = cls.isInstance(_)
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/reflect/scala/reflect/runtime/JavaMirrors.scala
Expand Up @@ -38,7 +38,7 @@ import internal.Flags._
import ReflectionUtils._
import scala.annotation.nowarn
import scala.reflect.api.TypeCreator
import scala.runtime.{ BoxesRunTime, ScalaRunTime }
import scala.runtime.{BoxesRunTime, ClassValueCompat, ScalaRunTime}

private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable =>

Expand Down Expand Up @@ -120,7 +120,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive
private[this] val fieldCache = new TwoWayCache[jField, TermSymbol]
private[this] val tparamCache = new TwoWayCache[jTypeVariable[_ <: GenericDeclaration], TypeSymbol]

private[this] object typeTagCache extends ClassValue[jWeakReference[TypeTag[_]]]() {
private[this] object typeTagCache extends ClassValueCompat[jWeakReference[TypeTag[_]]]() {
val typeCreator = new ThreadLocal[TypeCreator]()

override protected def computeValue(cls: jClass[_]): jWeakReference[TypeTag[_]] = {
Expand Down

0 comments on commit e18202b

Please sign in to comment.