All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sbt.internal.inc.LookupImpl.scala Maven / Gradle / Ivy

/*
 * Zinc - The incremental compiler for Scala.
 * Copyright Scala Center, Lightbend, and Mark Harrah
 *
 * Licensed under Apache License 2.0
 * SPDX-License-Identifier: Apache-2.0
 *
 * See the NOTICE file distributed with this work for
 * additional information regarding copyright ownership.
 */

package sbt.internal.inc

import java.util.Optional

import xsbti.compile.{ Changes, CompileAnalysis, FileHash, MiniSetup }
import xsbti.{ VirtualFile, VirtualFileRef }

class LookupImpl(compileConfiguration: CompileConfiguration, previousSetup: Option[MiniSetup])
    extends Lookup {
  private val classpath: Vector[VirtualFile] = compileConfiguration.classpath.toVector
  private val classpathHash: Vector[FileHash] =
    compileConfiguration.currentSetup.options.classpathHash.toVector

  import sbt.internal.inc.JavaInterfaceUtil.EnrichOptional
  lazy val analyses: Vector[Analysis] = {
    classpath flatMap { entry =>
      compileConfiguration.perClasspathEntryLookup.analysis(entry).toOption.map {
        case a: Analysis => a
      }
    }
  }

  lazy val previousClasspathHash: Vector[FileHash] = {
    previousSetup match {
      case Some(x) => x.options.classpathHash.toVector
      case _       => Vector()
    }
  }

  def changedClasspathHash: Option[Vector[FileHash]] =
    if (classpathHash == previousClasspathHash) None
    else Some(classpathHash)

  private val entry = MixedAnalyzingCompiler.classPathLookup(compileConfiguration)

  override def lookupAnalysis(binaryClassName: String): Option[CompileAnalysis] =
    analyses.find(_.relations.productClassName._2s.contains(binaryClassName))

  override def lookupOnClasspath(binaryClassName: String): Option[VirtualFileRef] =
    entry(binaryClassName)
      .map(compileConfiguration.converter.toVirtualFile(_))

  lazy val externalLookup = Option(compileConfiguration.incOptions.externalHooks())
    .flatMap(ext => ext.getExternalLookup().toOption)
    .collect { case externalLookup: ExternalLookup => externalLookup }

  override def lookupAnalyzedClass(binaryClassName: String, file: Option[VirtualFileRef]) = {
    externalLookup match { // not flatMap so that external lookup can fast-track returning None
      case Some(externalLookup) =>
        externalLookup.lookupAnalyzedClass(binaryClassName, file) match {
          case Some(api) if api.provenance.isEmpty => // found but w/o provenance, so go slow route
            super.lookupAnalyzedClass(binaryClassName, file)
          case x => x // fast-track success: either found w/ provenance or not found at all
        }
      case _ => super.lookupAnalyzedClass(binaryClassName, file)
    }
  }

  override def changedSources(previousAnalysis: CompileAnalysis): Option[Changes[VirtualFileRef]] =
    externalLookup.flatMap(_.changedSources(previousAnalysis))

  override def changedBinaries(previousAnalysis: CompileAnalysis): Option[Set[VirtualFileRef]] =
    externalLookup.flatMap(_.changedBinaries(previousAnalysis))

  override def removedProducts(
      previousAnalysis: CompileAnalysis
  ): Option[Set[VirtualFileRef]] =
    externalLookup.flatMap(_.removedProducts(previousAnalysis))

  override def shouldDoIncrementalCompilation(
      changedClasses: Set[String],
      analysis: CompileAnalysis
  ): Boolean =
    externalLookup.forall(_.shouldDoIncrementalCompilation(changedClasses, analysis))

  override def shouldDoEarlyOutput(analysis: CompileAnalysis): Boolean = {
    externalLookup match {
      case Some(externalLookup) => externalLookup.shouldDoEarlyOutput(analysis)
      case None                 => super.shouldDoEarlyOutput(analysis)
    }
  }

  override def hashClasspath(classpath: Array[VirtualFile]): Optional[Array[FileHash]] =
    externalLookup.map(_.hashClasspath(classpath)).getOrElse(Optional.empty())
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy