Documentation
¶
Overview ¶
Package contentmapper defines the types describing an external content mapper: a plugin that transforms otherwise unsupported file content (e.g. .vue) into virtual TypeScript during program construction.
A mapper is declared in tsconfig (Definition), its implementation is described by fields in its npm package's package.json (Manifest), and the two are combined once the package is resolved (Mapper). Resolution itself lives in the tsoptions package (it needs node module resolution).
The package also drives the configured content mappers at build time (Host): it spawns each mapper's package as a child process and talks to it over a JSON-RPC connection (reusing internal/ipc), turning content-mapped source files into virtual TypeScript. Processes are consolidated by mapper identity, so many projects that use the same mapper version share a single process.
Index ¶
- Constants
- Variables
- func CheckSupplementalFileNameCollisions(files SourceFiles, fileExists func(string) bool) error
- func IsSupportedVirtualExtension(extension string) bool
- type CloseProjectParams
- type Definition
- type Diagnostic
- type DiagnosticDirectiveError
- type DiagnosticDirectiveErrorKind
- type DiagnosticDirectivePolicy
- type DiagnosticDirectives
- type Host
- type HostOptions
- type InitializeError
- type InitializeErrorKind
- type InitializeParams
- type InitializeResult
- type InvalidVirtualExtensionError
- type Logger
- type Manifest
- type MappedDiagnosticDirective
- type MappedOutput
- type MappedResult
- type Mapper
- type MapperTimings
- type OpenProjectParams
- type OpenProjectResult
- type OperationTiming
- type OptionDiagnostic
- type OptionDiagnosticResult
- type OptionPathSegment
- type PositionEncoding
- type Project
- type ProjectError
- type ProjectErrorKind
- type ProjectSpec
- type Request
- type Result
- type SourceFiles
- type Spawner
- type SpawnerFunc
- type SupplementalFileCollisionError
- type SupplementalOutput
- type Timings
- type TransformError
- type TransformErrorKind
- type TransformParams
- type TransformResult
- type UnusedExpectDirectiveDiagnostic
Constants ¶
const ( MethodInitialize = "initialize" MethodOpenProject = "openProject" MethodCloseProject = "closeProject" MethodTransform = "transform" )
Content mapper protocol method names.
const ProtocolVersion = 1
ProtocolVersion is the content mapper protocol version this host speaks.
Variables ¶
Functions ¶
func CheckSupplementalFileNameCollisions ¶
func CheckSupplementalFileNameCollisions(files SourceFiles, fileExists func(string) bool) error
CheckSupplementalFileNameCollisions rejects compiler-assigned virtual filenames that name physical files.
Types ¶
type CloseProjectParams ¶
type CloseProjectParams struct {
ProjectHandle string `json:"projectHandle"`
}
CloseProjectParams is the parameter object for the closeProject request.
type Definition ¶
type Definition struct {
Package string `json:"package"`
Extensions []string `json:"extensions"`
Options json.Value `json:"options,omitempty"`
}
Definition is a content mapper as declared in a tsconfig's "contentMappers": the npm package that implements the mapper and the otherwise unsupported file extensions it registers.
type Diagnostic ¶
type Diagnostic struct {
// MessageText is the diagnostic message.
MessageText string `json:"messageText"`
// Start and Length locate the diagnostic in the original content using the selected position encoding.
Start int `json:"start"`
Length int `json:"length"`
Code int32 `json:"code,omitempty"`
}
Diagnostic is an error reported by a mapper in original-source coordinates.
type DiagnosticDirectiveError ¶
type DiagnosticDirectiveError struct {
Kind DiagnosticDirectiveErrorKind
Index int
SupplementalIndex int
Policy DiagnosticDirectivePolicy
}
DiagnosticDirectiveError reports an invalid diagnostic directive in a transform response.
func (*DiagnosticDirectiveError) Error ¶
func (e *DiagnosticDirectiveError) Error() string
type DiagnosticDirectiveErrorKind ¶
type DiagnosticDirectiveErrorKind uint8
DiagnosticDirectiveErrorKind identifies why a diagnostic directive was rejected.
const ( DiagnosticDirectiveErrorKindInvalidRange DiagnosticDirectiveErrorKind = iota DiagnosticDirectiveErrorKindInvalidPolicy DiagnosticDirectiveErrorKindExpectMissingUnusedDiagnostic DiagnosticDirectiveErrorKindInvalidUnusedDiagnosticIndex DiagnosticDirectiveErrorKindOverlap )
type DiagnosticDirectivePolicy ¶
type DiagnosticDirectivePolicy uint8
DiagnosticDirectivePolicy is the numeric policy stored in a mapped diagnostic directive tuple.
const ( DiagnosticDirectivePolicyIgnore DiagnosticDirectivePolicy = iota DiagnosticDirectivePolicyExpect )
type DiagnosticDirectives ¶
type DiagnosticDirectives struct {
UnusedExpectDirectiveDiagnostics []UnusedExpectDirectiveDiagnostic `json:"unusedExpectDirectiveDiagnostics"`
Directives []MappedDiagnosticDirective `json:"directives"`
}
DiagnosticDirectives shares unused-expect diagnostics across compact directive tuples.
type Host ¶
type Host interface {
// Timings returns a cumulative snapshot of mapper process and protocol activity.
Timings() Timings
// Project returns a retained project-scoped view for spec. Equivalent specs share underlying mapper
// configuration state; the caller must close the returned Project.
Project(spec ProjectSpec) Project
// Acquire retains the processes for the given mapper identities until the returned lease is released.
// Acquiring a mapper does not start its process; processes remain lazy until Transform is called.
Acquire(mappers []*Mapper) (release func())
// SetLocale updates the locale used to initialize mapper processes. Existing processes are stopped
// and respawned lazily so subsequent transforms use the new locale.
SetLocale(locale locale.Locale)
// Transform maps a content-mapped source file to virtual TypeScript using the given content mapper
// in a short-lived project with default compiler options.
//
// A non-nil error indicates the mapper itself failed to produce a result — for example the
// host hit a broken pipe, a process crash, or could not deserialize the mapper's response.
Transform(mapper *Mapper, request Request) (result Result, err error)
// Close shuts down every mapper process the host spawned.
Close() error
}
Host transforms otherwise unsupported file content into virtual TypeScript during program construction, by driving the configured content mappers. Create one with NewHost; Close tears down every mapper it spawned.
func NewHost ¶
NewHost creates a Host that spawns each mapper's process via the given spawner and drives it over a JSON-RPC connection. The host's lifetime is bound to ctx: cancelling it (e.g. the CLI's signal context on SIGINT, or a build/watch session ending) tears every mapper process down, so owners of a session context need not close the host explicitly. Close does the same synchronously.
func NewHostWithOptions ¶
func NewHostWithOptions(ctx context.Context, spawner Spawner, diagnosticLocale locale.Locale, options HostOptions) Host
NewHostWithOptions creates a Host with optional protocol and process logging.
type HostOptions ¶
type HostOptions struct {
Logger Logger
}
HostOptions configures optional content mapper process logging.
type InitializeError ¶
type InitializeError struct {
Kind InitializeErrorKind
MapperName string
Command string
Detail string
ExitCode int
TimeoutSeconds int
ProtocolVersion int
PositionEncoding PositionEncoding
DiagnosticSource string
}
InitializeError reports an invalid or unsupported mapper initialize response.
func (*InitializeError) Error ¶
func (e *InitializeError) Error() string
type InitializeErrorKind ¶
type InitializeErrorKind uint8
InitializeErrorKind identifies why a mapper's initialize response was rejected.
const ( InitializeErrorKindProcessStart InitializeErrorKind = iota InitializeErrorKindProcessExit InitializeErrorKindNoResponse InitializeErrorKindInvalidResponse InitializeErrorKindRequest InitializeErrorKindProtocolVersion InitializeErrorKindPositionEncoding InitializeErrorKindEmptyDiagnosticSource InitializeErrorKindReservedDiagnosticSource )
type InitializeParams ¶
type InitializeParams struct {
ProtocolVersion int `json:"protocolVersion"`
// Locale is the BCP 47 locale to use for mapper-authored diagnostic messages, when configured.
Locale string `json:"locale,omitempty"`
// PositionEncodings lists the coordinate spaces the host accepts.
PositionEncodings []PositionEncoding `json:"positionEncodings"`
}
InitializeParams is the parameter object for the initialize request.
type InitializeResult ¶
type InitializeResult struct {
ProtocolVersion int `json:"protocolVersion"`
// PositionEncoding selects the coordinate space for all mappings and diagnostics.
PositionEncoding PositionEncoding `json:"positionEncoding"`
// DiagnosticSource is the prefix used for every mapper-authored diagnostic code.
DiagnosticSource string `json:"diagnosticSource"`
}
InitializeResult is the mapper's response to the initialize request.
type InvalidVirtualExtensionError ¶
type InvalidVirtualExtensionError struct {
Extension string
}
InvalidVirtualExtensionError reports an unsupported or missing virtual extension on a mapped output.
func (*InvalidVirtualExtensionError) Error ¶
func (e *InvalidVirtualExtensionError) Error() string
type Logger ¶
type Logger func(message string)
Logger receives content mapper protocol and process output as complete log lines.
type Manifest ¶
type Manifest struct {
Name string
Version string
Exec []string
CompilerOptions []string
DynamicConfig bool
}
Manifest is the content-mapper information read from a package's package.json: its name and version (which form the mapper's identity), the argv used to run it, and the compiler options it declares it depends on.
type MappedDiagnosticDirective ¶
type MappedDiagnosticDirective struct {
OriginalStart int
OriginalLength int
VirtualStart int
VirtualEnd int
Policy DiagnosticDirectivePolicy
UnusedExpectDirectiveIndex *int
}
MappedDiagnosticDirective is encoded as [originalStart, originalLength, virtualStart, virtualEnd, policy, unusedExpectDirectiveIndex?]. An omitted index selects the only unused-expect diagnostic and is invalid when there is not exactly one.
func (MappedDiagnosticDirective) MarshalJSONTo ¶
func (d MappedDiagnosticDirective) MarshalJSONTo(enc *json.Encoder) error
func (*MappedDiagnosticDirective) UnmarshalJSONFrom ¶
func (d *MappedDiagnosticDirective) UnmarshalJSONFrom(dec *json.Decoder) error
type MappedOutput ¶
type MappedOutput struct {
// Text is the virtual JavaScript or TypeScript source text.
Text string `json:"text"`
// Extension determines the virtual source file's syntax.
Extension string `json:"extension"`
// Mappings is the span map's tuple-array JSON (see spanmap.Marshal), expressed in the selected
// position encoding. Absent or empty means the output is fully synthesized.
Mappings json.Value `json:"mappings,omitempty"`
// DiagnosticDirectives describe framework directives that suppress TypeScript diagnostics in
// virtual ranges and optionally report an error when no diagnostic is produced.
DiagnosticDirectives *DiagnosticDirectives `json:"diagnosticDirectives,omitempty"`
}
MappedOutput is virtual source text and its mapping to an original input.
type MappedResult ¶
type MappedResult struct {
Text string
VirtualExtension string
Mappings *spanmap.SpanMap
DiagnosticDirectives []ast.MappedDiagnosticDirective
}
MappedResult is one virtual source file and its mapping to the original input.
type Mapper ¶
type Mapper struct {
Definition
Manifest `json:"-"`
PackageDirectory string `json:"-"`
// ContributionID is provided by an LSP client extension for inferred project content mappers.
ContributionID string `json:"-"`
}
Mapper is a resolved content mapper: its tsconfig Definition combined with the Manifest resolved from the package's package.json, plus the package directory used as the mapper's working directory.
func (*Mapper) DiagnosticName ¶
DiagnosticName returns the best available user-facing name, including when manifest resolution failed.
func (*Mapper) Identity ¶
Identity returns the mapper's "name@version" identity, or just the name when it declares no version, or an empty string when the mapper has not been resolved to a name.
func (*Mapper) MarshalDeclaredOptions ¶
func (m *Mapper) MarshalDeclaredOptions(options *core.CompilerOptions) (*collections.OrderedMap[string, json.Value], error)
MarshalDeclaredOptions marshals just the compiler options this mapper declared it depends on, in the declared order, skipping any that are unset. Marshaling only the declared fields avoids serializing the whole CompilerOptions when a mapper depends on few options (or none).
func (*Mapper) TransformIdentity ¶
func (m *Mapper) TransformIdentity(options *core.CompilerOptions) xxh3.Uint128
TransformIdentity returns a fingerprint of everything besides a file's content that determines the output of transforming it with this mapper under the given options: the mapper's identity and the values of the compiler options it declared it depends on. Folding it into a cache key means a change to the mapper version or a relevant compiler option invalidates cached results. It is a pure function of the mapper and options — the declared options come from the manifest, so it never starts the mapper process.
type MapperTimings ¶
type MapperTimings struct {
Spawn OperationTiming
Initialize OperationTiming
OpenProject OperationTiming
CloseProject OperationTiming
Transform OperationTiming
}
MapperTimings is cumulative process and protocol activity for one resolved mapper identity.
type OpenProjectParams ¶
type OpenProjectParams struct {
// ConfigFileName is the absolute project configuration file name, or empty when there is none.
ConfigFileName string `json:"configFileName"`
// ProjectHandle is an opaque, process-local handle assigned by the host.
ProjectHandle string `json:"projectHandle"`
// Options is the mapper entry's options from the project's contentMappers configuration.
Options json.Value `json:"options,omitempty"`
// CompilerOptions contains the project's effective compiler options.
CompilerOptions json.Value `json:"compilerOptions"`
}
OpenProjectParams is the parameter object for the openProject request.
type OpenProjectResult ¶
type OpenProjectResult struct {
// ConfigIdentity is a stable fingerprint of all dynamic configuration that can affect transforms.
ConfigIdentity string `json:"configIdentity"`
// WatchedFiles are absolute files whose changes may alter ConfigIdentity or transform output.
WatchedFiles []string `json:"watchedFiles,omitempty"`
// OptionDiagnostics report invalid mapper options. Paths are relative to the mapper entry's options object.
OptionDiagnostics []OptionDiagnosticResult `json:"optionDiagnostics,omitempty"`
}
OpenProjectResult is the mapper's response to an openProject request. ConfigIdentity and WatchedFiles may only be returned by mappers that declare dynamicConfig.
type OperationTiming ¶
OperationTiming is the cumulative wall time and invocation count for one mapper operation.
type OptionDiagnostic ¶
type OptionDiagnostic struct {
Mapper *Mapper
Path []OptionPathSegment
Source string
Code int32
MessageText string
}
type OptionDiagnosticResult ¶
type OptionPathSegment ¶
type PositionEncoding ¶
type PositionEncoding string
PositionEncoding is the coordinate space a mapper uses for mappings and diagnostics.
const ( PositionEncodingUTF8 PositionEncoding = "utf-8" PositionEncodingUTF16 PositionEncoding = "utf-16" )
type Project ¶
type Project interface {
// Refresh closes opened mapper projects so they are reopened on the next transform or configuration identity query.
Refresh() error
// Identities returns sorted transform identities for all configured mappers. It returns an error if
// dynamic project configuration cannot be opened or validated.
Identities() ([]string, error)
// Identity returns the transform identity for mapper, or an empty string if mapper is not in this
// project. It returns an error if dynamic project configuration cannot be opened or validated.
Identity(mapper *Mapper) (string, error)
// WatchedFiles returns the absolute files reported by mappers whose package.json declares dynamicConfig.
// It returns an error if project configuration cannot be opened or validated.
WatchedFiles() ([]string, error)
// Diagnostics returns option diagnostics cached by mapper projects that have already been opened.
Diagnostics() []OptionDiagnostic
// Transform transforms one content-mapped source file using mapper in this project's configuration.
Transform(mapper *Mapper, request Request) (result Result, err error)
// Close releases this project reference and closes mapper project handles when no references remain.
Close() error
}
Project is the project-scoped view of a Host. It owns mapper configuration handles and provides the identities and watch dependencies needed for caching and incremental builds. Mapper projects are opened lazily when a transform is requested, or earlier when dynamic configuration is needed.
type ProjectError ¶
type ProjectError struct {
Kind ProjectErrorKind
}
ProjectError reports an invalid mapper openProject response.
func (*ProjectError) Error ¶
func (e *ProjectError) Error() string
type ProjectErrorKind ¶
type ProjectErrorKind uint8
ProjectErrorKind identifies why a mapper's openProject response was rejected.
const ( ProjectErrorKindMalformedResponse ProjectErrorKind = iota ProjectErrorKindMissingConfigIdentity ProjectErrorKindNonAbsoluteWatchedFile ProjectErrorKindUnexpectedConfigIdentity ProjectErrorKindUnexpectedWatchedFiles )
type ProjectSpec ¶
type ProjectSpec struct {
// ConfigFileName is the absolute project configuration file name, or empty for a project without one.
ConfigFileName string
// Mappers are the resolved content mapper entries configured for the project.
Mappers []*Mapper
// CompilerOptions are the project's effective compiler options.
CompilerOptions *core.CompilerOptions
}
ProjectSpec describes the project configuration visible to its content mappers.
type Request ¶
type Request struct {
// FileName is the content-mapped source file being transformed.
FileName string
// Content is the content-mapped source file's text.
Content string
}
Request carries the inputs for transforming one content-mapped source file.
type Result ¶
type Result struct {
// Text is the virtual TypeScript source text that is parsed into the program.
Text string
// VirtualExtension determines how Text is parsed.
VirtualExtension string
// Diagnostics are syntax errors in the original content.
Diagnostics []*ast.Diagnostic
// Mappings maps positions in Text back to the original content, so that diagnostics the compiler
// produces against the virtual text can be reported at their original locations. A successful
// transform must return a non-nil map; an empty map describes fully synthesized output.
Mappings *spanmap.SpanMap
// DiagnosticDirectives control TypeScript diagnostics produced in virtual ranges.
DiagnosticDirectives []ast.MappedDiagnosticDirective
// Supplemental contains additional unnamed outputs associated with the canonical result.
Supplemental []MappedResult
}
Result is the outcome of transforming a content-mapped source file into virtual TypeScript.
type SourceFiles ¶
type SourceFiles struct {
Canonical *ast.SourceFile
Supplemental []*ast.SourceFile
}
SourceFiles is the canonical output and its unnamed supplemental compiler inputs.
func ParseResult ¶
func ParseResult(parseOptions ast.SourceFileParseOptions, content string, mapper *Mapper, transformIdentity string, result Result) (SourceFiles, error)
ParseResult validates and parses one mapper result and all its supplemental outputs.
func TransformAndParse ¶
func TransformAndParse( parseOptions ast.SourceFileParseOptions, content string, mapper *Mapper, project Project, ) (SourceFiles, error)
TransformAndParse runs the given content mapper's transform for a content-mapped source file and parses the resulting TypeScript, preserving the original file name and retaining the untransformed text on the source file. The mapper is supplied by the caller (which also owns the failure accounting) so it is neither re-resolved nor substituted here. It returns an error if the transform fails or the mapper produces invalid position mappings (a *spanmap.MappingError); the caller decides how to report the failure and what placeholder file to substitute. It is the shared implementation behind CompilerHost.GetContentMappedSourceFile.
type Spawner ¶
type Spawner interface {
Spawn(command []string, dir string, stderr io.Writer) (io.ReadWriteCloser, error)
}
Spawner starts a child process, returning its stdio as an io.ReadWriteCloser (Read is the process's stdout, Write is its stdin) whose Close tears the process down. This seam keeps os/exec out of this package: production hosts spawn a real process, tests supply an in-process pipe.
type SpawnerFunc ¶
SpawnerFunc adapts a spawn function to the Spawner interface.
func (SpawnerFunc) Spawn ¶
func (f SpawnerFunc) Spawn(command []string, dir string, stderr io.Writer) (io.ReadWriteCloser, error)
type SupplementalFileCollisionError ¶
type SupplementalFileCollisionError struct {
FileName string
}
SupplementalFileCollisionError reports a compiler-assigned supplemental filename that already exists.
func (*SupplementalFileCollisionError) Error ¶
func (e *SupplementalFileCollisionError) Error() string
type SupplementalOutput ¶
type SupplementalOutput struct {
MappedOutput
}
type Timings ¶
type Timings struct {
Mappers map[string]MapperTimings
RequestWait time.Duration
}
Timings is a cumulative snapshot of content mapper process and protocol activity.
type TransformError ¶
type TransformError struct {
Kind TransformErrorKind
// contains filtered or unexported fields
}
TransformError reports a failure while preparing, requesting, or decoding a transform.
func NewTransformError ¶
func NewTransformError(kind TransformErrorKind, err error) *TransformError
NewTransformError creates a transform error for the given stage and underlying error.
func (*TransformError) Error ¶
func (e *TransformError) Error() string
func (*TransformError) Unwrap ¶
func (e *TransformError) Unwrap() error
type TransformErrorKind ¶
type TransformErrorKind uint8
TransformErrorKind identifies the stage at which a content mapper transform failed.
const ( TransformErrorKindUnknown TransformErrorKind = iota TransformErrorKindInitialize TransformErrorKindProject TransformErrorKindRequest TransformErrorKindResponse TransformErrorKindMappings )
type TransformParams ¶
type TransformParams struct {
// FileName is the absolute name of the content-mapped source file being transformed.
FileName string `json:"fileName"`
// Content is the content-mapped source file's text.
Content string `json:"content"`
// ProjectHandle identifies the mapper project configuration opened for this transform.
ProjectHandle string `json:"projectHandle"`
}
TransformParams is the parameter object for the transform request.
type TransformResult ¶
type TransformResult struct {
MappedOutput
// Diagnostics are mapper-authored errors expressed in original-source coordinates.
Diagnostics []Diagnostic `json:"diagnostics,omitempty"`
// Supplemental contains additional unnamed compiler inputs associated with this source file.
Supplemental []SupplementalOutput `json:"supplemental,omitempty"`
}
TransformResult is the canonical output for one input file.