mirror of
https://github.com/fluencelabs/aqua.git
synced 2024-12-04 14:40:17 +00:00
feat(language-server): Resolve paths for imports (#1079)
This commit is contained in:
parent
e2b150a786
commit
245f6640f8
@ -1,5 +1,7 @@
|
|||||||
aqua A
|
aqua A
|
||||||
|
|
||||||
|
import "aqua-src/gen/OneMore.aqua"
|
||||||
|
|
||||||
export main
|
export main
|
||||||
|
|
||||||
alias SomeAlias: string
|
alias SomeAlias: string
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
aqua One
|
||||||
|
|
||||||
service OneMore:
|
service OneMore:
|
||||||
more_call()
|
more_call()
|
||||||
consume(s: string)
|
consume(s: string)
|
@ -82,7 +82,7 @@ lazy val `language-server-api` = crossProject(JSPlatform, JVMPlatform)
|
|||||||
"co.fs2" %%% "fs2-io" % fs2V
|
"co.fs2" %%% "fs2-io" % fs2V
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.dependsOn(compiler, io)
|
.dependsOn(compiler, io, compiler % "test->test")
|
||||||
|
|
||||||
lazy val `language-server-apiJS` = `language-server-api`.js
|
lazy val `language-server-apiJS` = `language-server-api`.js
|
||||||
.settings(
|
.settings(
|
||||||
|
@ -3,17 +3,18 @@ package aqua.compiler
|
|||||||
import aqua.compiler.AquaError.*
|
import aqua.compiler.AquaError.*
|
||||||
import aqua.linker.Linker
|
import aqua.linker.Linker
|
||||||
import aqua.parser.{Ast, ParserError}
|
import aqua.parser.{Ast, ParserError}
|
||||||
|
import aqua.semantics.header.Picker.setImportPaths
|
||||||
import aqua.semantics.header.{HeaderHandler, Picker}
|
import aqua.semantics.header.{HeaderHandler, Picker}
|
||||||
import aqua.semantics.{SemanticError, Semantics}
|
import aqua.semantics.{FileId, SemanticError, Semantics}
|
||||||
|
|
||||||
import cats.arrow.FunctionK
|
import cats.arrow.FunctionK
|
||||||
import cats.data.*
|
import cats.data.*
|
||||||
import cats.syntax.either.*
|
import cats.syntax.either.*
|
||||||
import cats.syntax.functor.*
|
import cats.syntax.functor.*
|
||||||
import cats.{Comonad, Monad, Monoid, Order, ~>}
|
import cats.syntax.show.*
|
||||||
|
import cats.{~>, Comonad, Monad, Monoid, Order, Show}
|
||||||
import scribe.Logging
|
import scribe.Logging
|
||||||
|
|
||||||
class AquaCompiler[F[_]: Monad, E, I: Order, S[_]: Comonad, C: Monoid: Picker](
|
class AquaCompiler[F[_]: Monad, E, I: FileId, S[_]: Comonad, C: Monoid: Picker](
|
||||||
headerHandler: HeaderHandler[S, C],
|
headerHandler: HeaderHandler[S, C],
|
||||||
semantics: Semantics[S, C]
|
semantics: Semantics[S, C]
|
||||||
) extends Logging {
|
) extends Logging {
|
||||||
@ -27,7 +28,7 @@ class AquaCompiler[F[_]: Monad, E, I: Order, S[_]: Comonad, C: Monoid: Picker](
|
|||||||
// (Imports contexts => Compilation result)
|
// (Imports contexts => Compilation result)
|
||||||
type TP = Map[String, C] => CompileRes[C]
|
type TP = Map[String, C] => CompileRes[C]
|
||||||
|
|
||||||
private def transpile(body: Ast[S]): TP =
|
private def transpile(body: Ast[S], importPaths: Map[String, String]): TP =
|
||||||
imports =>
|
imports =>
|
||||||
for {
|
for {
|
||||||
// Process header, get initial context
|
// Process header, get initial context
|
||||||
@ -43,7 +44,7 @@ class AquaCompiler[F[_]: Monad, E, I: Order, S[_]: Comonad, C: Monoid: Picker](
|
|||||||
rc <- headerSem
|
rc <- headerSem
|
||||||
.finCtx(processed)
|
.finCtx(processed)
|
||||||
.toCompileRes
|
.toCompileRes
|
||||||
} yield rc
|
} yield rc.setImportPaths(importPaths)
|
||||||
|
|
||||||
def compileRaw(
|
def compileRaw(
|
||||||
sources: AquaSources[F, E, I],
|
sources: AquaSources[F, E, I],
|
||||||
@ -58,7 +59,10 @@ class AquaCompiler[F[_]: Monad, E, I: Order, S[_]: Comonad, C: Monoid: Picker](
|
|||||||
// Lift resolution to CompileRes
|
// Lift resolution to CompileRes
|
||||||
modules <- resolution.toEitherT[CompileWarns]
|
modules <- resolution.toEitherT[CompileWarns]
|
||||||
// Generate transpilation functions for each module
|
// Generate transpilation functions for each module
|
||||||
transpiled = modules.map(body => transpile(body))
|
transpiled = modules.map { m =>
|
||||||
|
val importPaths = m.imports.view.mapValues(_.show).toMap
|
||||||
|
m.copy(body = transpile(m.body, importPaths))
|
||||||
|
}
|
||||||
// Link modules
|
// Link modules
|
||||||
linked <- Linker.link(transpiled, CycleError.apply)
|
linked <- Linker.link(transpiled, CycleError.apply)
|
||||||
} yield linked
|
} yield linked
|
||||||
|
@ -5,21 +5,21 @@ import aqua.compiler.AquaError.*
|
|||||||
import aqua.model.AquaContext
|
import aqua.model.AquaContext
|
||||||
import aqua.parser.{Ast, ParserError}
|
import aqua.parser.{Ast, ParserError}
|
||||||
import aqua.raw.RawContext
|
import aqua.raw.RawContext
|
||||||
import aqua.semantics.RawSemantics
|
|
||||||
import aqua.semantics.header.{HeaderHandler, HeaderSem}
|
import aqua.semantics.header.{HeaderHandler, HeaderSem}
|
||||||
import aqua.semantics.rules.locations.{LocationsAlgebra, DummyLocationsInterpreter}
|
import aqua.semantics.rules.locations.{DummyLocationsInterpreter, LocationsAlgebra}
|
||||||
|
import aqua.semantics.{FileId, RawSemantics}
|
||||||
|
|
||||||
import cats.data.*
|
import cats.data.*
|
||||||
import cats.syntax.either.*
|
import cats.syntax.either.*
|
||||||
import cats.syntax.flatMap.*
|
import cats.syntax.flatMap.*
|
||||||
import cats.syntax.functor.*
|
import cats.syntax.functor.*
|
||||||
import cats.syntax.traverse.*
|
import cats.syntax.traverse.*
|
||||||
import cats.{Comonad, Monad, Monoid, Order}
|
import cats.{Comonad, Monad, Monoid, Order, Show}
|
||||||
import scribe.Logging
|
import scribe.Logging
|
||||||
|
|
||||||
object CompilerAPI extends Logging {
|
object CompilerAPI extends Logging {
|
||||||
|
|
||||||
private def toAquaProcessed[I: Order, E, S[_]: Comonad](
|
private def toAquaProcessed[I: FileId, S[_]: Comonad](
|
||||||
filesWithContext: Map[I, RawContext]
|
filesWithContext: Map[I, RawContext]
|
||||||
): Chain[AquaProcessed[I]] = {
|
): Chain[AquaProcessed[I]] = {
|
||||||
logger.trace("linking finished")
|
logger.trace("linking finished")
|
||||||
@ -41,7 +41,7 @@ object CompilerAPI extends Logging {
|
|||||||
.value
|
.value
|
||||||
}
|
}
|
||||||
|
|
||||||
private def getAquaCompiler[F[_]: Monad, E, I: Order, S[_]: Comonad](
|
private def getAquaCompiler[F[_]: Monad, E, I: FileId, S[_]: Comonad](
|
||||||
config: AquaCompilerConf
|
config: AquaCompilerConf
|
||||||
): AquaCompiler[F, E, I, S, RawContext] = {
|
): AquaCompiler[F, E, I, S, RawContext] = {
|
||||||
given Monoid[RawContext] = RawContext
|
given Monoid[RawContext] = RawContext
|
||||||
@ -55,8 +55,8 @@ object CompilerAPI extends Logging {
|
|||||||
.rawContextMonoid
|
.rawContextMonoid
|
||||||
|
|
||||||
val semantics = new RawSemantics[S]()
|
val semantics = new RawSemantics[S]()
|
||||||
|
|
||||||
given LocationsAlgebra[S, State[RawContext, *]] =
|
given LocationsAlgebra[S, State[RawContext, *]] =
|
||||||
DummyLocationsInterpreter()
|
DummyLocationsInterpreter()
|
||||||
|
|
||||||
new AquaCompiler[F, E, I, S, RawContext](
|
new AquaCompiler[F, E, I, S, RawContext](
|
||||||
@ -66,7 +66,7 @@ object CompilerAPI extends Logging {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get result generated by backend
|
// Get result generated by backend
|
||||||
def compile[F[_]: Monad, E, I: Order, S[_]: Comonad](
|
def compile[F[_]: Monad, E, I: FileId, S[_]: Comonad](
|
||||||
sources: AquaSources[F, E, I],
|
sources: AquaSources[F, E, I],
|
||||||
parser: I => String => ValidatedNec[ParserError[S], Ast[S]],
|
parser: I => String => ValidatedNec[ParserError[S], Ast[S]],
|
||||||
airValidator: AirValidator[F],
|
airValidator: AirValidator[F],
|
||||||
@ -104,7 +104,7 @@ object CompilerAPI extends Logging {
|
|||||||
} yield result
|
} yield result
|
||||||
}
|
}
|
||||||
|
|
||||||
def compileToContext[F[_]: Monad, E, I: Order, S[_]: Comonad](
|
def compileToContext[F[_]: Monad, E, I: FileId, S[_]: Comonad](
|
||||||
sources: AquaSources[F, E, I],
|
sources: AquaSources[F, E, I],
|
||||||
parser: I => String => ValidatedNec[ParserError[S], Ast[S]],
|
parser: I => String => ValidatedNec[ParserError[S], Ast[S]],
|
||||||
config: AquaCompilerConf
|
config: AquaCompilerConf
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package aqua.compiler
|
package aqua.compiler
|
||||||
|
|
||||||
|
import aqua.compiler.FileIdString.given
|
||||||
import aqua.model.AquaContext
|
import aqua.model.AquaContext
|
||||||
import aqua.model.CallServiceModel
|
import aqua.model.CallServiceModel
|
||||||
import aqua.model.FlattenModel
|
import aqua.model.FlattenModel
|
||||||
@ -16,6 +17,7 @@ import aqua.raw.ConstantRaw
|
|||||||
import aqua.raw.value.{LiteralRaw, ValueRaw, VarRaw}
|
import aqua.raw.value.{LiteralRaw, ValueRaw, VarRaw}
|
||||||
import aqua.res.*
|
import aqua.res.*
|
||||||
import aqua.res.ResBuilder
|
import aqua.res.ResBuilder
|
||||||
|
import aqua.semantics.FileId
|
||||||
import aqua.types.{ArrayType, CanonStreamType, LiteralType, ScalarType, StreamType, Type}
|
import aqua.types.{ArrayType, CanonStreamType, LiteralType, ScalarType, StreamType, Type}
|
||||||
|
|
||||||
import cats.Id
|
import cats.Id
|
||||||
|
11
compiler/src/test/scala/aqua/compiler/FileIdString.scala
Normal file
11
compiler/src/test/scala/aqua/compiler/FileIdString.scala
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package aqua.compiler
|
||||||
|
|
||||||
|
import aqua.semantics.FileId
|
||||||
|
|
||||||
|
object FileIdString {
|
||||||
|
given FileId[String] with {
|
||||||
|
override def show(t: String): String = t
|
||||||
|
|
||||||
|
override def compare(x: String, y: String): Int = x.compare(y)
|
||||||
|
}
|
||||||
|
}
|
@ -1,18 +1,20 @@
|
|||||||
package aqua.files
|
package aqua.files
|
||||||
|
|
||||||
|
import aqua.semantics.FileId
|
||||||
import fs2.io.file.Path
|
import fs2.io.file.Path
|
||||||
import cats.Order
|
import cats.{Order, Show}
|
||||||
|
|
||||||
case class FileModuleId private (file: Path) {
|
case class FileModuleId private (file: Path) {
|
||||||
override def toString: String = s"${file}"
|
override def toString: String = s"$file"
|
||||||
}
|
}
|
||||||
|
|
||||||
object FileModuleId {
|
object FileModuleId {
|
||||||
|
|
||||||
implicit object FileModuleIdOrder extends Order[FileModuleId] {
|
given FileId[FileModuleId] with {
|
||||||
|
|
||||||
override def compare(x: FileModuleId, y: FileModuleId): Int =
|
override def compare(x: FileModuleId, y: FileModuleId): Int =
|
||||||
x.file.toString.compareTo(y.file.toString)
|
x.file.toString.compareTo(y.file.toString)
|
||||||
|
|
||||||
|
override def show(t: FileModuleId): String = t.toString
|
||||||
}
|
}
|
||||||
|
|
||||||
def apply(file: Path): FileModuleId =
|
def apply(file: Path): FileModuleId =
|
||||||
|
@ -107,11 +107,12 @@ object ResultHelper extends Logging {
|
|||||||
link.toList
|
link.toList
|
||||||
}.toJSArray
|
}.toJSArray
|
||||||
|
|
||||||
private def importsToTokenImport(imports: List[LiteralToken[FileSpan.F]]): js.Array[TokenImport] =
|
private def importsToTokenImport(imports: List[LiteralToken[FileSpan.F]], importPaths: Map[String, String]): js.Array[TokenImport] =
|
||||||
imports.flatMap { lt =>
|
imports.flatMap { lt =>
|
||||||
val (span, str) = lt.valueToken
|
val (span, str) = lt.valueToken
|
||||||
val unquoted = str.substring(1, str.length - 1)
|
val unquoted = str.substring(1, str.length - 1)
|
||||||
TokenLocation.fromSpan(span).map(l => TokenImport(l, unquoted))
|
val path = importPaths.getOrElse(unquoted, unquoted)
|
||||||
|
TokenLocation.fromSpan(span).map(l => TokenImport(l, path))
|
||||||
}.toJSArray
|
}.toJSArray
|
||||||
|
|
||||||
def lspToCompilationResult(lsp: LspContext[FileSpan.F]): CompilationResult = {
|
def lspToCompilationResult(lsp: LspContext[FileSpan.F]): CompilationResult = {
|
||||||
@ -124,11 +125,13 @@ object ResultHelper extends Logging {
|
|||||||
case errs =>
|
case errs =>
|
||||||
logger.debug("Errors: " + errs.mkString("\n"))
|
logger.debug("Errors: " + errs.mkString("\n"))
|
||||||
|
|
||||||
|
val importTokens = importsToTokenImport(lsp.importTokens, lsp.importPaths)
|
||||||
|
|
||||||
CompilationResult(
|
CompilationResult(
|
||||||
errors.toJSArray,
|
errors.toJSArray,
|
||||||
warnings.toJSArray,
|
warnings.toJSArray,
|
||||||
locationsToJs(lsp.variables.flatMap(v => v.allLocations)),
|
locationsToJs(lsp.variables.flatMap(v => v.allLocations)),
|
||||||
importsToTokenImport(lsp.importTokens),
|
importTokens,
|
||||||
tokensToJs(lsp.variables.map(_.definition))
|
tokensToJs(lsp.variables.map(_.definition))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,18 @@ import aqua.parser.{Ast, ParserError}
|
|||||||
import aqua.raw.RawContext
|
import aqua.raw.RawContext
|
||||||
import aqua.semantics.header.{HeaderHandler, HeaderSem}
|
import aqua.semantics.header.{HeaderHandler, HeaderSem}
|
||||||
import aqua.semantics.rules.locations.LocationsAlgebra
|
import aqua.semantics.rules.locations.LocationsAlgebra
|
||||||
|
import aqua.semantics.FileId
|
||||||
import cats.data.Validated.validNec
|
import cats.data.Validated.validNec
|
||||||
import cats.data.{State, Chain, Validated, ValidatedNec}
|
import cats.data.{Chain, State, Validated, ValidatedNec}
|
||||||
import cats.syntax.either.*
|
import cats.syntax.either.*
|
||||||
import cats.syntax.functor.*
|
import cats.syntax.functor.*
|
||||||
import cats.syntax.monoid.*
|
import cats.syntax.monoid.*
|
||||||
import cats.syntax.semigroup.*
|
import cats.syntax.semigroup.*
|
||||||
import cats.{Comonad, Monad, Monoid, Order}
|
import cats.{Comonad, Monad, Monoid, Order, Show}
|
||||||
|
|
||||||
object LSPCompiler {
|
object LSPCompiler {
|
||||||
|
|
||||||
private def getLspAquaCompiler[F[_]: Monad, E, I: Order, S[_]: Comonad](
|
private def getLspAquaCompiler[F[_]: Monad, E, I: FileId, S[_]: Comonad](
|
||||||
config: AquaCompilerConf
|
config: AquaCompilerConf
|
||||||
): AquaCompiler[F, E, I, S, LspContext[S]] = {
|
): AquaCompiler[F, E, I, S, LspContext[S]] = {
|
||||||
given Monoid[LspContext[S]] = LspContext
|
given Monoid[LspContext[S]] = LspContext
|
||||||
@ -48,7 +48,7 @@ object LSPCompiler {
|
|||||||
|
|
||||||
val semantics = new LspSemantics[S]()
|
val semantics = new LspSemantics[S]()
|
||||||
|
|
||||||
given LocationsAlgebra[S, State[LspContext[S], *]] =
|
given LocationsAlgebra[S, State[LspContext[S], *]] =
|
||||||
LocationsInterpreter[S, LspContext[S]]()
|
LocationsInterpreter[S, LspContext[S]]()
|
||||||
|
|
||||||
new AquaCompiler[F, E, I, S, LspContext[S]](
|
new AquaCompiler[F, E, I, S, LspContext[S]](
|
||||||
@ -57,7 +57,7 @@ object LSPCompiler {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def compileToLsp[F[_]: Monad, E, I: Order, S[_]: Comonad](
|
def compileToLsp[F[_]: Monad, E, I: FileId, S[_]: Comonad](
|
||||||
sources: AquaSources[F, E, I],
|
sources: AquaSources[F, E, I],
|
||||||
parser: I => String => ValidatedNec[ParserError[S], Ast[S]],
|
parser: I => String => ValidatedNec[ParserError[S], Ast[S]],
|
||||||
config: AquaCompilerConf
|
config: AquaCompilerConf
|
||||||
|
@ -22,7 +22,8 @@ case class LspContext[S[_]](
|
|||||||
variables: List[VariableInfo[S]] = Nil,
|
variables: List[VariableInfo[S]] = Nil,
|
||||||
importTokens: List[LiteralToken[S]] = Nil,
|
importTokens: List[LiteralToken[S]] = Nil,
|
||||||
errors: List[SemanticError[S]] = Nil,
|
errors: List[SemanticError[S]] = Nil,
|
||||||
warnings: List[SemanticWarning[S]] = Nil
|
warnings: List[SemanticWarning[S]] = Nil,
|
||||||
|
importPaths: Map[String, String] = Map.empty
|
||||||
) {
|
) {
|
||||||
lazy val allLocations: List[TokenLocation[S]] = variables.flatMap(_.allLocations)
|
lazy val allLocations: List[TokenLocation[S]] = variables.flatMap(_.allLocations)
|
||||||
}
|
}
|
||||||
@ -41,7 +42,8 @@ object LspContext {
|
|||||||
importTokens = x.importTokens ++ y.importTokens,
|
importTokens = x.importTokens ++ y.importTokens,
|
||||||
variables = x.variables ++ y.variables,
|
variables = x.variables ++ y.variables,
|
||||||
errors = x.errors ++ y.errors,
|
errors = x.errors ++ y.errors,
|
||||||
warnings = x.warnings ++ y.warnings
|
warnings = x.warnings ++ y.warnings,
|
||||||
|
importPaths = x.importPaths ++ y.importPaths
|
||||||
)
|
)
|
||||||
|
|
||||||
trait Implicits[S[_]] {
|
trait Implicits[S[_]] {
|
||||||
@ -101,6 +103,9 @@ object LspContext {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override def setImportPaths(ctx: LspContext[S], importPaths: Map[String, String]): LspContext[S] =
|
||||||
|
ctx.copy(importPaths = importPaths)
|
||||||
|
|
||||||
override def setModule(
|
override def setModule(
|
||||||
ctx: LspContext[S],
|
ctx: LspContext[S],
|
||||||
name: Option[String],
|
name: Option[String],
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package aqua.lsp
|
package aqua.lsp
|
||||||
|
|
||||||
|
import aqua.compiler.FileIdString.given_FileId_String
|
||||||
import aqua.compiler.{AquaCompilerConf, AquaError, AquaSources}
|
import aqua.compiler.{AquaCompilerConf, AquaError, AquaSources}
|
||||||
import aqua.parser.Parser
|
import aqua.parser.Parser
|
||||||
import aqua.parser.lift.Span
|
import aqua.parser.lift.Span
|
||||||
@ -10,7 +11,6 @@ import aqua.types.*
|
|||||||
|
|
||||||
import cats.Id
|
import cats.Id
|
||||||
import cats.data.*
|
import cats.data.*
|
||||||
import cats.instances.string.*
|
|
||||||
import org.scalatest.Inside
|
import org.scalatest.Inside
|
||||||
import org.scalatest.flatspec.AnyFlatSpec
|
import org.scalatest.flatspec.AnyFlatSpec
|
||||||
import org.scalatest.matchers.should.Matchers
|
import org.scalatest.matchers.should.Matchers
|
||||||
@ -423,7 +423,8 @@ class AquaLSPSpec extends AnyFlatSpec with Matchers with Inside {
|
|||||||
),
|
),
|
||||||
ProductType(nestedType :: Nil)
|
ProductType(nestedType :: Nil)
|
||||||
)
|
)
|
||||||
), ("check2", ArrowType(NilType, ProductType(someStr :: Nil))),
|
),
|
||||||
|
("check2", ArrowType(NilType, ProductType(someStr :: Nil))),
|
||||||
("check3", ArrowType(NilType, ProductType(ScalarType.string :: Nil)))
|
("check3", ArrowType(NilType, ProductType(ScalarType.string :: Nil)))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
package aqua.linker
|
package aqua.linker
|
||||||
|
|
||||||
case class AquaModule[I, E, T](id: I, imports: Map[String, I], dependsOn: Map[I, E], body: T) {
|
case class AquaModule[I, E, T](id: I, imports: Map[String, I], dependsOn: Map[I, E], body: T)
|
||||||
def map[TT](f: T => TT): AquaModule[I, E, TT] = copy(body = f(body))
|
|
||||||
|
|
||||||
def mapWithId[TT](f: (I, T) => TT): AquaModule[I, E, TT] = copy(body = f(id, body))
|
|
||||||
|
|
||||||
def mapErr[EE](f: E => EE): AquaModule[I, EE, T] =
|
|
||||||
copy(dependsOn = dependsOn.view.mapValues(f).toMap)
|
|
||||||
}
|
|
||||||
|
@ -30,14 +30,8 @@ case class Modules[I, E, T](
|
|||||||
|
|
||||||
def isResolved: Boolean = dependsOn.isEmpty
|
def isResolved: Boolean = dependsOn.isEmpty
|
||||||
|
|
||||||
def map[TT](f: T => TT): Modules[I, E, TT] =
|
def map[TT](f: AquaModule[I, E, T] => AquaModule[I, E, TT]): Modules[I, E, TT] =
|
||||||
copy(loaded = loaded.view.mapValues(_.map(f)).toMap)
|
copy(loaded = loaded.view.mapValues(f).toMap)
|
||||||
|
|
||||||
def mapErr[EE](f: E => EE): Modules[I, EE, T] =
|
|
||||||
copy(
|
|
||||||
loaded = loaded.view.mapValues(_.mapErr(f)).toMap,
|
|
||||||
dependsOn = dependsOn.view.mapValues(_.map(f)).toMap
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object Modules {
|
object Modules {
|
||||||
|
7
semantics/src/main/scala/aqua/semantics/FileId.scala
Normal file
7
semantics/src/main/scala/aqua/semantics/FileId.scala
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package aqua.semantics
|
||||||
|
|
||||||
|
import cats.Show
|
||||||
|
import cats.kernel.Order
|
||||||
|
import cats.syntax.order.*
|
||||||
|
|
||||||
|
trait FileId[I] extends Show[I] with Order[I]
|
@ -22,6 +22,7 @@ trait Picker[A] {
|
|||||||
def funcAcceptAbility(ctx: A, name: String): Boolean
|
def funcAcceptAbility(ctx: A, name: String): Boolean
|
||||||
def declares(ctx: A): Set[String]
|
def declares(ctx: A): Set[String]
|
||||||
def setAbility(ctx: A, name: String, ctxAb: A): A
|
def setAbility(ctx: A, name: String, ctxAb: A): A
|
||||||
|
def setImportPaths(ctx: A, importPaths: Map[String, String]): A
|
||||||
def setModule(ctx: A, name: Option[String], declares: Set[String]): A
|
def setModule(ctx: A, name: Option[String], declares: Set[String]): A
|
||||||
def setExports(ctx: A, exports: Map[String, Option[String]]): A
|
def setExports(ctx: A, exports: Map[String, Option[String]]): A
|
||||||
def setInit(ctx: A, ctxInit: Option[A]): A
|
def setInit(ctx: A, ctxInit: Option[A]): A
|
||||||
@ -51,6 +52,7 @@ object Picker {
|
|||||||
def funcAcceptAbility(name: String): Boolean = Picker[A].funcAcceptAbility(p, name)
|
def funcAcceptAbility(name: String): Boolean = Picker[A].funcAcceptAbility(p, name)
|
||||||
def declares: Set[String] = Picker[A].declares(p)
|
def declares: Set[String] = Picker[A].declares(p)
|
||||||
def setAbility(name: String, ctx: A): A = Picker[A].setAbility(p, name, ctx)
|
def setAbility(name: String, ctx: A): A = Picker[A].setAbility(p, name, ctx)
|
||||||
|
def setImportPaths(importPaths: Map[String, String]): A = Picker[A].setImportPaths(p, importPaths)
|
||||||
def setInit(ctx: Option[A]): A = Picker[A].setInit(p, ctx)
|
def setInit(ctx: Option[A]): A = Picker[A].setInit(p, ctx)
|
||||||
def addPart(part: (A, RawPart)): A = Picker[A].addPart(p, part)
|
def addPart(part: (A, RawPart)): A = Picker[A].addPart(p, part)
|
||||||
|
|
||||||
@ -117,6 +119,10 @@ object Picker {
|
|||||||
override def setAbility(ctx: RawContext, name: String, ctxAb: RawContext): RawContext =
|
override def setAbility(ctx: RawContext, name: String, ctxAb: RawContext): RawContext =
|
||||||
ctx.copy(abilities = Map(name -> ctxAb))
|
ctx.copy(abilities = Map(name -> ctxAb))
|
||||||
|
|
||||||
|
// dummy
|
||||||
|
override def setImportPaths(ctx: RawContext, importPaths: Map[String, String]): RawContext =
|
||||||
|
ctx
|
||||||
|
|
||||||
override def setModule(
|
override def setModule(
|
||||||
ctx: RawContext,
|
ctx: RawContext,
|
||||||
name: Option[String],
|
name: Option[String],
|
||||||
|
Loading…
Reference in New Issue
Block a user