aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/config/JavaPlatform.scala
blob: 8bc18c387229369bd72f9052b7dded712f4fb43d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package dotty.tools
package dotc
package config

import io.{AbstractFile,ClassPath,JavaClassPath,MergedClassPath,DeltaClassPath}
import ClassPath.{ JavaContext, DefaultJavaContext }
import core._
import Symbols._, Types._, Contexts._, Denotations._, SymDenotations._, StdNames._, Names._
import Flags._, Scopes._, Decorators._, NameOps._, util.Positions._
import transform.ExplicitOuter, transform.SymUtils._

class JavaPlatform extends Platform {

  private var currentClassPath: Option[MergedClassPath] = None

  def classPath(implicit ctx: Context): ClassPath = {
    if (currentClassPath.isEmpty)
      currentClassPath = Some(new PathResolver().result)
    val cp = currentClassPath.get
    cp
  }

  // The given symbol is a method with the right name and signature to be a runnable java program.
  def isJavaMainMethod(sym: SymDenotation)(implicit ctx: Context) =
    (sym.name == nme.main) && (sym.info match {
      case MethodTpe(_, defn.ArrayOf(el) :: Nil, restpe) => el =:= defn.StringType && (restpe isRef defn.UnitClass)
      case _ => false
    })

  // The given class has a main method.
  def hasJavaMainMethod(sym: Symbol)(implicit ctx: Context): Boolean =
    (sym.info member nme.main).hasAltWith {
      case x: SymDenotation => isJavaMainMethod(x)
      case _ => false
    }

  /** Update classpath with a substituted subentry */
  def updateClassPath(subst: Map[ClassPath, ClassPath]) =
    currentClassPath = Some(new DeltaClassPath(currentClassPath.get, subst))

  def rootLoader(root: TermSymbol)(implicit ctx: Context): SymbolLoader = new ctx.base.loaders.PackageLoader(root, classPath)

  /** Is the SAMType `cls` also a SAM under the rules of the JVM? */
  def isSam(cls: ClassSymbol)(implicit ctx: Context): Boolean =
    cls.is(NoInitsTrait) &&
    cls.superClass == defn.ObjectClass &&
    cls.directlyInheritedTraits.forall(_.is(NoInits)) &&
    !ExplicitOuter.needsOuterIfReferenced(cls) &&
    cls.typeRef.fields.isEmpty // Superaccessors already show up as abstract methods here, so no test necessary

  /** We could get away with excluding BoxedBooleanClass for the
   *  purpose of equality testing since it need not compare equal
   *  to anything but other booleans, but it should be present in
   *  case this is put to other uses.
   */
  def isMaybeBoxed(sym: ClassSymbol)(implicit ctx: Context) = {
    val d = defn
    import d._
    (sym == ObjectClass) ||
    (sym == JavaSerializableClass) ||
    (sym == ComparableClass) ||
    (sym derivesFrom BoxedNumberClass) ||
    (sym derivesFrom BoxedCharClass) ||
    (sym derivesFrom BoxedBooleanClass)
  }

  def newClassLoader(bin: AbstractFile)(implicit ctx: Context): SymbolLoader =
    new ClassfileLoader(bin)
}