Revert "syntax-highlighter: scip-ctags implementation (#50600)" (#52642)

This reverts commit 1ff6fb12d9.



## Test plan

<!-- All pull requests REQUIRE a test plan:
https://docs.sourcegraph.com/dev/background-information/testing_principles
-->
This commit is contained in:
Eric Fritz 2023-05-30 13:29:57 -05:00 committed by GitHub
parent 7e1e59d9fd
commit 9554353f0b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
93 changed files with 900 additions and 4304 deletions

View File

@ -22,10 +22,10 @@ go_library(
"//internal/honey",
"//internal/observation",
"//internal/trace/ot",
"//lib/codeintel/languages",
"//lib/errors",
"@com_github_alecthomas_chroma_v2//:chroma",
"@com_github_alecthomas_chroma_v2//lexers",
"@com_github_go_enry_go_enry_v2//:go-enry",
"@com_github_grafana_regexp//:regexp",
"@com_github_inconshreveable_log15//:log15",
"@com_github_prometheus_client_golang//prometheus",
@ -33,6 +33,7 @@ go_library(
"@com_github_sourcegraph_scip//bindings/go/scip",
"@io_opentelemetry_go_otel//attribute",
"@org_golang_google_protobuf//proto",
"@org_golang_x_exp//slices",
"@org_golang_x_net//html",
"@org_golang_x_net//html/atom",
],

View File

@ -5,12 +5,13 @@ import (
"path/filepath"
"strings"
"github.com/go-enry/go-enry/v2"
"github.com/grafana/regexp"
"golang.org/x/exp/slices"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/conf/conftypes"
"github.com/sourcegraph/sourcegraph/internal/gosyntect"
"github.com/sourcegraph/sourcegraph/lib/codeintel/languages"
)
type EngineType int
@ -246,11 +247,45 @@ func getLanguage(path string, contents string) (string, bool) {
return lang, true
}
// TODO: Consider if we should just ignore getting empty...?
lang, _ = languages.GetLanguage(path, contents)
// Force the use of the shebang.
if shebangLang, ok := overrideViaShebang(path, contents); ok {
return shebangLang, false
}
// Lastly, fall back to whatever enry decides is a useful algorithm for calculating.
lang = enry.GetLanguage(path, []byte(contents))
return lang, false
}
// overrideViaShebang handles explicitly using the shebang whenever possible.
//
// It also covers some edge cases when enry eagerly returns more languages
// than necessary, which ends up overriding the shebang completely (which,
// IMO is the highest priority match we can have).
//
// For example, enry will return "Perl" and "Pod" for a shebang of `#!/usr/bin/env perl`.
// This is actually unhelpful, because then enry will *not* select "Perl" as the
// language (which is our desired behavior).
func overrideViaShebang(path, content string) (lang string, ok bool) {
shebangs := enry.GetLanguagesByShebang(path, []byte(content), []string{})
if len(shebangs) == 0 {
return "", false
}
if len(shebangs) == 1 {
return shebangs[0], true
}
// There are some shebangs that enry returns that are not really
// useful for our syntax highlighters to distinguish between.
if slices.Equal(shebangs, []string{"Perl", "Pod"}) {
return "Perl", true
}
return "", false
}
// DetectSyntaxHighlightingLanguage will calculate the SyntaxEngineQuery from a given
// path and contents. First it will determine if there are any configuration overrides
// and then, if none, return the 'enry' default language detection

View File

@ -28,7 +28,6 @@ OSS_TARGETS=(
//cmd/gitserver
//cmd/searcher
//cmd/server
//docker-images/syntax-highlighter:scip-ctags
# https://github.com/sourcegraph/s3proxy is still the default for now.
# //cmd/blobstore
@com_github_sourcegraph_zoekt//cmd/zoekt-archive-index
@ -47,7 +46,6 @@ ENTERPRISE_TARGETS=(
//enterprise/cmd/repo-updater
//enterprise/cmd/precise-code-intel-worker
//enterprise/cmd/server
//docker-images/syntax-highlighter:scip-ctags
)
MUSL_TARGETS=(

View File

@ -1,27 +1,11 @@
# NOTE: This layer of the docker image is also used in local development as a wrapper around universal-ctags
FROM sourcegraph/alpine-3.14:213466_2023-04-17_5.0-bdda34a71619@sha256:6354a4ff578b685e36c8fbde81f62125ae0011b047fb2cc22d1b0de616b3c59a AS ctags
# hadolint ignore=DL3002
USER root
COPY cmd/symbols/ctags-install-alpine.sh /ctags-install-alpine.sh
RUN /ctags-install-alpine.sh
FROM rust:1.68.0-alpine3.17@sha256:d119a621ae12f84ec0c5fed77c24795120ed1c7874b2428b5a6ccc0f294dbe18 as scip-ctags
# hadolint ignore=DL3002
USER root
RUN apk add --no-cache musl-dev>=1.1.24-r10 build-base
COPY docker-images/syntax-highlighter /repo
WORKDIR /repo
RUN cargo fetch
ARG TARGETARCH
# Because .cargo/config.toml doesnt support triplet-specific env
COPY cmd/symbols/cargo-config.sh /cargo-config.sh
RUN /cargo-config.sh
RUN cargo rustc --release --bin scip-ctags
RUN cp ./target/release/scip-ctags /usr/local/bin/scip-ctags
FROM golang:1.19.8-alpine@sha256:841c160ed35923d96c95c52403c4e6db5decd9cbce034aa851e412ade5d4b74f AS symbols-build
# hadolint ignore=DL3002
USER root
@ -76,7 +60,6 @@ LABEL com.sourcegraph.github.url=https://github.com/sourcegraph/sourcegraph/comm
RUN apk add --no-cache bind-tools ca-certificates mailcap tini jansson libstdc++ libgcc
COPY --from=ctags /usr/local/bin/universal-ctags /usr/local/bin/universal-ctags
COPY --from=scip-ctags /usr/local/bin/scip-ctags /usr/local/bin/scip-ctags
COPY --from=symbols-build /symbols /usr/local/bin/symbols

View File

@ -29,9 +29,6 @@ RUN apk add --no-cache bind-tools ca-certificates mailcap tini jansson libstdc++
COPY --from=ctags /usr/local/bin/universal-ctags /usr/local/bin/universal-ctags
# the scip binary and symbols was already built by bazel
# see cmd/symbols/build-bazel.sh where it is built and put in the context directory aka $OUTPUT for docker
COPY scip-ctags /usr/local/bin/scip-ctags
COPY symbols /usr/local/bin/symbols
# symbols is cgo, ensure we have the requisite dynamic libraries

View File

@ -11,7 +11,7 @@ cleanup() {
}
trap cleanup EXIT
echo "--- :bazel: bazel build for targets //cmd/symbols"
echo "--- bazel build"
bazelrc=(
--bazelrc=.bazelrc
@ -23,6 +23,7 @@ if [[ ${CI:-""} == "true" ]]; then
)
fi
bazel "${bazelrc[@]}" \
build \
//cmd/symbols \
@ -38,31 +39,9 @@ out=$(
--config incompat-zig-linux-amd64 \
--output=files
)
cp -v "$out" "$OUTPUT"
# we can't build scip-ctags with symbols since the platform args conflict
# NOTE: cmd/symbols/cargo-config.sh sets some specific config when running on arm64
# since this bazel run typically runs on CI that config change isn't made
echo "--- :bazel: bazel build for target //docker-images/syntax-highlighter:scip-ctags"
bazel "${bazelrc[@]}" \
build //docker-images/syntax-highlighter:scip-ctags \
--stamp \
--workspace_status_command=./dev/bazel_stamp_vars.sh
out=$(
bazel "${bazelrc[@]}" \
cquery //docker-images/syntax-highlighter:scip-ctags \
--stamp \
--workspace_status_command=./dev/bazel_stamp_vars.sh \
--output=files
)
cp -v "$out" "$OUTPUT"
cp "$out" "$OUTPUT"
cp cmd/symbols/ctags-install-alpine.sh "$OUTPUT"
echo ":docker: context directory contains the following:"
ls -lah "$OUTPUT"
echo "--- :docker: docker build for symbols"
docker build -f cmd/symbols/Dockerfile.bazel -t "$IMAGE" "$OUTPUT" \
--progress=plain \
--build-arg COMMIT_SHA \

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
# This script builds the ctags images for local development.
# This script builds the ctags image for local development.
cd "$(dirname "${BASH_SOURCE[0]}")/../.."
set -eu
@ -9,30 +9,12 @@ set -eu
# image. See /dev/universal-ctags-dev.
if [[ "${CTAGS_COMMAND}" != "dev/universal-ctags-dev" ]]; then
echo "CTAGS_COMMAND set to custom executable. Building of Docker image not necessary."
else
# Build ctags docker image for universal-ctags-dev
echo "Building universal-ctags docker image"
docker build -f cmd/symbols/Dockerfile -t ctags . \
--platform linux/amd64 \
--target=ctags \
--progress=plain
exit 0
fi
# If SCIP_CTAGS_COMMAND is set to a custom executable, we don't need to build the
# image. See /dev/scip-ctags-dev.
if [[ "${SCIP_CTAGS_COMMAND}" != "dev/scip-ctags-dev" ]]; then
echo "SCIP_CTAGS_COMMAND set to custom executable. Building of Docker image or Rust code not necessary."
else
if [[ "$(uname -m)" == "arm64" ]]; then
# build ctags with cargo; prevent x86-64 slowdown on mac
root="$(dirname "${BASH_SOURCE[0]}")/../.." >/dev/null
"$root"/dev/scip-ctags-install.sh
else
# Build ctags docker image for scip-ctags-dev
echo "Building scip-ctags docker image"
docker build -f cmd/symbols/Dockerfile -t scip-ctags . \
--platform linux/amd64 \
--target=scip-ctags \
--progress=plain
fi
fi
# Build ctags docker image for universal-ctags-dev
echo "Building ctags docker image"
docker build -f cmd/symbols/Dockerfile -t ctags . \
--platform linux/amd64 \
--target=ctags \
--progress=plain

View File

@ -1,8 +0,0 @@
#!/bin/sh
if [ "${TARGETARCH}" = "arm64" ]; then
cat <<- FOE >> .cargo/config.toml
[env]
CFLAGS="-mno-outline-atomics"
FOE
fi;

View File

@ -1,6 +1,6 @@
#!/bin/sh
# This script installs universal-ctags within an alpine container.
# This script installs ctags within an alpine container.
# Commit hash of github.com/universal-ctags/ctags.
# Last bumped 2022-04-04.

View File

@ -52,7 +52,6 @@ go_test(
"//cmd/symbols/internal/database/writer",
"//cmd/symbols/parser",
"//internal/api",
"//internal/ctags_config",
"//internal/database",
"//internal/diskcache",
"//internal/endpoint",

View File

@ -17,7 +17,6 @@ import (
symbolsdatabase "github.com/sourcegraph/sourcegraph/cmd/symbols/internal/database"
"github.com/sourcegraph/sourcegraph/cmd/symbols/internal/database/writer"
"github.com/sourcegraph/sourcegraph/cmd/symbols/parser"
"github.com/sourcegraph/sourcegraph/internal/ctags_config"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/diskcache"
"github.com/sourcegraph/sourcegraph/internal/endpoint"
@ -39,7 +38,7 @@ func TestHandler(t *testing.T) {
cache := diskcache.NewStore(tmpDir, "symbols", diskcache.WithBackgroundTimeout(20*time.Minute))
parserFactory := func(source ctags_config.ParserType) (ctags.Parser, error) {
parserFactory := func() (ctags.Parser, error) {
pathToEntries := map[string][]*ctags.Entry{
"a.js": {
{

View File

@ -3,7 +3,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "parser",
srcs = [
"config.go",
"filtering_parser.go",
"observability.go",
"parser.go",
@ -14,14 +13,10 @@ go_library(
deps = [
"//cmd/symbols/fetcher",
"//cmd/symbols/types",
"//internal/conf",
"//internal/conf/conftypes",
"//internal/ctags_config",
"//internal/metrics",
"//internal/observation",
"//internal/search",
"//internal/search/result",
"//lib/codeintel/languages",
"//lib/errors",
"@com_github_inconshreveable_log15//:log15",
"@com_github_prometheus_client_golang//prometheus",

View File

@ -1,63 +0,0 @@
package parser
import (
"fmt"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/conf/conftypes"
"github.com/sourcegraph/sourcegraph/internal/ctags_config"
)
var parserConfig = ctags_config.ParserConfiguration{
Default: ctags_config.UniversalCtags,
Engine: map[string]ctags_config.ParserType{},
}
func init() {
// Validation only: Do NOT set any values in the configuration in this function.
conf.ContributeValidator(func(c conftypes.SiteConfigQuerier) (problems conf.Problems) {
configuration := c.SiteConfig().SyntaxHighlighting
if configuration == nil {
return
}
for _, engine := range configuration.Symbols.Engine {
if _, err := ctags_config.ParserNameToParserType(engine); err != nil {
problems = append(problems, conf.NewSiteProblem(fmt.Sprintf("Not a valid Symbols.Engine: `%s`.", engine)))
}
}
return
})
go func() {
conf.Watch(func() {
c := conf.Get()
configuration := c.SiteConfig().SyntaxHighlighting
// Set the defaults
parserConfig.Engine = make(map[string]ctags_config.ParserType)
for lang, engine := range ctags_config.BaseParserConfig.Engine {
parserConfig.Engine[lang] = engine
}
if configuration != nil {
for lang, engine := range configuration.Symbols.Engine {
if engine, err := ctags_config.ParserNameToParserType(engine); err != nil {
parserConfig.Engine[lang] = engine
}
}
}
})
}()
}
func GetParserType(language string) ctags_config.ParserType {
parserType, ok := parserConfig.Engine[language]
if !ok {
return parserConfig.Default
} else {
return parserType
}
}

View File

@ -15,11 +15,9 @@ import (
"github.com/sourcegraph/sourcegraph/cmd/symbols/fetcher"
"github.com/sourcegraph/sourcegraph/cmd/symbols/types"
"github.com/sourcegraph/sourcegraph/internal/ctags_config"
"github.com/sourcegraph/sourcegraph/internal/observation"
"github.com/sourcegraph/sourcegraph/internal/search"
"github.com/sourcegraph/sourcegraph/internal/search/result"
"github.com/sourcegraph/sourcegraph/lib/codeintel/languages"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
@ -136,29 +134,14 @@ func min(a, b int) int {
return b
}
func (p *parser) handleParseRequest(
ctx context.Context,
symbolOrErrors chan<- SymbolOrError,
parseRequest fetcher.ParseRequest,
totalSymbols *uint32,
) (err error) {
func (p *parser) handleParseRequest(ctx context.Context, symbolOrErrors chan<- SymbolOrError, parseRequest fetcher.ParseRequest, totalSymbols *uint32) (err error) {
ctx, trace, endObservation := p.operations.handleParseRequest.With(ctx, &err, observation.Args{Attrs: []attribute.KeyValue{
attribute.String("path", parseRequest.Path),
attribute.Int("fileSize", len(parseRequest.Data)),
}})
defer endObservation(1, observation.Args{})
language, found := languages.GetLanguage(parseRequest.Path, string(parseRequest.Data))
if !found {
return nil
}
source := GetParserType(language)
if source == ctags_config.NoCtags || source == ctags_config.UnknownCtags {
return nil
}
parser, err := p.parserFromPool(ctx, source)
parser, err := p.parserFromPool(ctx)
if err != nil {
return err
}
@ -172,12 +155,12 @@ func (p *parser) handleParseRequest(
}
if err == nil {
p.parserPool.Done(parser, source)
p.parserPool.Done(parser)
} else {
// Close parser and return nil to pool, indicating that the next receiver should create a new parser
log15.Error("Closing failed parser", "error", err)
parser.Close()
p.parserPool.Done(nil, source)
p.parserPool.Done(nil)
p.operations.parseFailed.Inc()
}
}()
@ -236,15 +219,11 @@ func (p *parser) handleParseRequest(
return nil
}
func (p *parser) parserFromPool(ctx context.Context, source ctags_config.ParserType) (ctags.Parser, error) {
if source == ctags_config.NoCtags || source == ctags_config.UnknownCtags {
return nil, errors.New("Should not pass NoCtags to this function")
}
func (p *parser) parserFromPool(ctx context.Context) (ctags.Parser, error) {
p.operations.parseQueueSize.Inc()
defer p.operations.parseQueueSize.Dec()
parser, err := p.parserPool.Get(ctx, source)
parser, err := p.parserPool.Get(ctx)
if err != nil {
if err == context.DeadlineExceeded {
p.operations.parseQueueTimeouts.Inc()
@ -271,20 +250,12 @@ func shouldPersistEntry(e *ctags.Entry) bool {
return true
}
func SpawnCtags(logger log.Logger, ctagsConfig types.CtagsConfig, source ctags_config.ParserType) (ctags.Parser, error) {
func SpawnCtags(logger log.Logger, ctagsConfig types.CtagsConfig) (ctags.Parser, error) {
logger = logger.Scoped("ctags", "ctags processes")
var options ctags.Options
if source == ctags_config.UniversalCtags {
options = ctags.Options{
Bin: ctagsConfig.UniversalCommand,
PatternLengthLimit: ctagsConfig.PatternLengthLimit,
}
} else {
options = ctags.Options{
Bin: ctagsConfig.ScipCommand,
PatternLengthLimit: ctagsConfig.PatternLengthLimit,
}
options := ctags.Options{
Bin: ctagsConfig.Command,
PatternLengthLimit: ctagsConfig.PatternLengthLimit,
}
if ctagsConfig.LogErrors {
options.Info = std.NewLogger(logger, log.LevelInfo)

View File

@ -4,39 +4,29 @@ import (
"context"
"github.com/sourcegraph/go-ctags"
"github.com/sourcegraph/sourcegraph/internal/ctags_config"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
type ParserFactory func(ctags_config.ParserType) (ctags.Parser, error)
type ParserFactory func() (ctags.Parser, error)
type parserPool struct {
newParser ParserFactory
pool map[ctags_config.ParserType]chan ctags.Parser
pool chan ctags.Parser
}
func NewParserPool(newParser ParserFactory, numParserProcesses int) (*parserPool, error) {
pool := make(map[ctags_config.ParserType]chan ctags.Parser)
// NOTE: We obviously don't make `NoCtags` available in the pool.
for _, parserType := range []ctags_config.ParserType{ctags_config.UniversalCtags, ctags_config.ScipCtags} {
pool[parserType] = make(chan ctags.Parser, numParserProcesses)
for i := 0; i < numParserProcesses; i++ {
parser, err := newParser(parserType)
if err != nil {
return nil, err
}
pool[parserType] <- parser
pool := make(chan ctags.Parser, numParserProcesses)
for i := 0; i < numParserProcesses; i++ {
parser, err := newParser()
if err != nil {
return nil, err
}
pool <- parser
}
parserPool := &parserPool{
return &parserPool{
newParser: newParser,
pool: pool,
}
return parserPool, nil
}, nil
}
// Get a parser from the pool. Once this parser is no longer in use, the Done method
@ -45,27 +35,20 @@ func NewParserPool(newParser ParserFactory, numParserProcesses int) (*parserPool
// the pool. This method always returns a non-nil parser with a nil error value.
//
// This method blocks until a parser is available or the given context is canceled.
func (p *parserPool) Get(ctx context.Context, source ctags_config.ParserType) (ctags.Parser, error) {
if source == ctags_config.NoCtags || source == ctags_config.UnknownCtags {
return nil, errors.New("NoCtags is not a valid ParserType")
}
pool := p.pool[source]
func (p *parserPool) Get(ctx context.Context) (ctags.Parser, error) {
select {
case parser := <-pool:
case parser := <-p.pool:
if parser != nil {
return parser, nil
}
return p.newParser(source)
return p.newParser()
case <-ctx.Done():
return nil, ctx.Err()
}
}
func (p *parserPool) Done(parser ctags.Parser, source ctags_config.ParserType) {
pool := p.pool[source]
pool <- parser
func (p *parserPool) Done(parser ctags.Parser) {
p.pool <- parser
}

View File

@ -23,7 +23,6 @@ go_library(
"//internal/conf",
"//internal/conf/conftypes",
"//internal/conf/deploy",
"//internal/ctags_config",
"//internal/database",
"//internal/database/connections/live",
"//internal/debugserver",

View File

@ -19,7 +19,6 @@ import (
symbolparser "github.com/sourcegraph/sourcegraph/cmd/symbols/parser"
"github.com/sourcegraph/sourcegraph/cmd/symbols/types"
"github.com/sourcegraph/sourcegraph/internal/conf/deploy"
"github.com/sourcegraph/sourcegraph/internal/ctags_config"
"github.com/sourcegraph/sourcegraph/internal/database"
"github.com/sourcegraph/sourcegraph/internal/diskcache"
"github.com/sourcegraph/sourcegraph/internal/goroutine"
@ -47,7 +46,7 @@ func SetupSqlite(observationCtx *observation.Context, db database.DB, gitserverC
// anything that tries to open a SQLite database.
sqlite.Init()
if deploy.IsSingleBinary() && config.Ctags.UniversalCommand == "" {
if deploy.IsSingleBinary() && config.Ctags.Command == "" {
// app: ctags is not available
searchFunc := func(ctx context.Context, params search.SymbolsParameters) (result.Symbols, error) {
return nil, nil
@ -55,8 +54,8 @@ func SetupSqlite(observationCtx *observation.Context, db database.DB, gitserverC
return searchFunc, nil, []goroutine.BackgroundRoutine{}, "", nil
}
parserFactory := func(source ctags_config.ParserType) (ctags.Parser, error) {
return symbolparser.SpawnCtags(logger, config.Ctags, source)
parserFactory := func() (ctags.Parser, error) {
return symbolparser.SpawnCtags(logger, config.Ctags)
}
parserPool, err := symbolparser.NewParserPool(parserFactory, config.NumCtagsProcesses)
if err != nil {
@ -77,5 +76,5 @@ func SetupSqlite(observationCtx *observation.Context, db database.DB, gitserverC
cacheSizeBytes := int64(config.CacheSizeMB) * 1000 * 1000
cacheEvicter := janitor.NewCacheEvicter(evictionInterval, cache, cacheSizeBytes, janitor.NewMetrics(observationCtx))
return searchFunc, nil, []goroutine.BackgroundRoutine{cacheEvicter}, config.Ctags.UniversalCommand, nil
return searchFunc, nil, []goroutine.BackgroundRoutine{cacheEvicter}, config.Ctags.Command, nil
}

View File

@ -45,8 +45,7 @@ func LoadSqliteConfig(baseConfig env.BaseConfig, ctags CtagsConfig, repositoryFe
}
type CtagsConfig struct {
UniversalCommand string
ScipCommand string
Command string
PatternLengthLimit int
LogErrors bool
DebugLogs bool
@ -65,14 +64,8 @@ func LoadCtagsConfig(baseConfig env.BaseConfig) CtagsConfig {
ctagsCommandDefault = ""
}
scipCtagsCommandDefault := "scip-ctags"
if deploy.IsSingleBinary() {
scipCtagsCommandDefault = ""
}
return CtagsConfig{
UniversalCommand: baseConfig.Get("CTAGS_COMMAND", ctagsCommandDefault, "ctags command (should point to universal-ctags executable compiled with JSON and seccomp support)"),
ScipCommand: baseConfig.Get("SCIP_CTAGS_COMMAND", scipCtagsCommandDefault, "scip-ctags command"),
Command: baseConfig.Get("CTAGS_COMMAND", ctagsCommandDefault, "ctags command (should point to universal-ctags executable compiled with JSON and seccomp support)"),
PatternLengthLimit: baseConfig.GetInt("CTAGS_PATTERN_LENGTH_LIMIT", "250", "the maximum length of the patterns output by ctags"),
LogErrors: baseConfig.GetBool("LOG_CTAGS_ERRORS", logCtagsErrorsDefault, "log ctags errors"),
DebugLogs: false,

View File

@ -1,22 +0,0 @@
#!/usr/bin/env bash
# This script is a wrapper around `scip-ctags`.
#
# It checks if scip-ctags has been installed through ./dev/scip-ctags-install.sh or falls back to a dockerized version.
#
# To use your own `scip-ctags` binary instead of this wrapper in your local dev server, use
# `SCIP_CTAGS_COMMAND=path/to/ctags sg start`.
root="$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null
TARGET=$("$root/dev/scip-ctags-install.sh" which)
if [ ! -f "${TARGET}" ]; then
exec docker run --rm -i \
-a stdin -a stdout -a stderr \
--user guest \
--name=scip-ctags-$$ \
--entrypoint /usr/local/bin/scip-ctags \
scip-ctags "$@"
else
${TARGET} "$@"
fi

View File

@ -1,35 +0,0 @@
#!/usr/bin/env bash
set -euf -o pipefail
pushd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null
mkdir -p .bin
# TODO: add similar task to zoekt alpine
NAME="scip-ctags"
TARGET="$PWD/.bin/${NAME}"
if [ $# -ne 0 ]; then
if [ "$1" == "which" ]; then
echo "$TARGET"
exit 0
fi
fi
function ctrl_c() {
printf "[-] Installation cancelled.\n"
exit 1
}
trap ctrl_c INT
function build_scip_ctags {
cd docker-images/syntax-highlighter
cargo fetch
cargo build --bin scip-ctags --release
cp ./target/release/scip-ctags "$TARGET"
}
build_scip_ctags
popd >/dev/null

View File

@ -1,9 +1,3 @@
target
languages/libraries/
.vscode/
bench_data/
**/flamegraph.svg
**/perf.data
**/perf.data.old

View File

@ -12,7 +12,6 @@ rust_binary(
normal = True,
) + [
"//docker-images/syntax-highlighter/crates/sg-syntax:sg-syntax",
"//docker-images/syntax-highlighter/crates/scip-syntax:scip-syntax",
"//docker-images/syntax-highlighter/crates/scip-treesitter-languages:scip-treesitter-languages",
],
)
@ -32,17 +31,3 @@ rust_test(
normal_dev = True,
),
)
rust_binary(
name = "scip-ctags",
srcs = ["src/bin/scip-ctags.rs"],
aliases = aliases(),
proc_macro_deps = all_crate_deps(
proc_macro = True,
),
deps = all_crate_deps(
normal = True,
) + [
"//docker-images/syntax-highlighter/crates/scip-syntax:scip-syntax",
],
)

File diff suppressed because it is too large Load Diff

View File

@ -17,12 +17,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "anes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "ansi_term"
version = "0.12.1"
@ -135,18 +129,6 @@ version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1"
[[package]]
name = "bitvec"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "bumpalo"
version = "3.9.1"
@ -159,12 +141,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
version = "1.0.73"
@ -177,45 +153,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "ciborium"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369"
[[package]]
name = "ciborium-ll"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b"
dependencies = [
"ciborium-io",
"half",
]
[[package]]
name = "clap"
version = "3.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
dependencies = [
"bitflags 1.3.2",
"clap_lex 0.2.4",
"indexmap",
"textwrap",
]
[[package]]
name = "clap"
version = "4.1.11"
@ -224,7 +161,7 @@ checksum = "42dfd32784433290c51d92c438bb72ea5063797fc3cc9a21a8c4346bebbb2098"
dependencies = [
"bitflags 2.0.2",
"clap_derive",
"clap_lex 0.3.3",
"clap_lex",
"is-terminal",
"once_cell",
"strsim",
@ -244,15 +181,6 @@ dependencies = [
"syn",
]
[[package]]
name = "clap_lex"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "clap_lex"
version = "0.3.3"
@ -311,85 +239,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "criterion"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb"
dependencies = [
"anes",
"atty",
"cast",
"ciborium",
"clap 3.2.23",
"criterion-plot",
"itertools",
"lazy_static",
"num-traits",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
dependencies = [
"cast",
"itertools",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset 0.8.0",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
dependencies = [
"cfg-if",
]
[[package]]
name = "ctor"
version = "0.1.22"
@ -576,12 +425,6 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "futures"
version = "0.3.27"
@ -720,12 +563,6 @@ dependencies = [
"tracing",
]
[[package]]
name = "half"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
[[package]]
name = "hashbrown"
version = "0.11.2"
@ -879,30 +716,12 @@ dependencies = [
"windows-sys 0.45.0",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "js-sys"
version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -1010,15 +829,6 @@ dependencies = [
"autocfg",
]
[[package]]
name = "memoffset"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
dependencies = [
"autocfg",
]
[[package]]
name = "mime"
version = "0.3.16"
@ -1097,7 +907,7 @@ dependencies = [
"cc",
"cfg-if",
"libc",
"memoffset 0.6.5",
"memoffset",
]
[[package]]
@ -1109,15 +919,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
@ -1139,9 +940,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.17.1"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "onig"
@ -1165,12 +966,6 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "oorandom"
version = "11.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]]
name = "os_str_bytes"
version = "6.5.0"
@ -1278,34 +1073,6 @@ dependencies = [
"xml-rs",
]
[[package]]
name = "plotters"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142"
[[package]]
name = "plotters-svg"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f"
dependencies = [
"plotters-backend",
]
[[package]]
name = "ppv-lite86"
version = "0.2.16"
@ -1405,12 +1172,6 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "radium"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "radix_trie"
version = "0.2.1"
@ -1451,28 +1212,6 @@ dependencies = [
"getrandom",
]
[[package]]
name = "rayon"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
name = "redox_syscall"
version = "0.2.13"
@ -1746,19 +1485,14 @@ name = "scip-syntax"
version = "0.1.0"
dependencies = [
"anyhow",
"bitvec",
"clap 4.1.11",
"clap",
"insta",
"itertools",
"once_cell",
"protobuf",
"rustc-hash",
"scip",
"scip-macros",
"scip-treesitter",
"scip-treesitter-languages",
"serde",
"serde_json",
"tree-sitter",
"walkdir",
]
@ -2078,17 +1812,13 @@ dependencies = [
name = "syntect_server"
version = "1.0.1"
dependencies = [
"base64",
"clap 4.1.11",
"criterion",
"clap",
"futures",
"futures-task",
"futures-util",
"protobuf",
"rocket",
"rustyline",
"scip",
"scip-syntax",
"scip-treesitter",
"scip-treesitter-languages",
"serde",
@ -2097,12 +1827,6 @@ dependencies = [
"syntect",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "tempfile"
version = "3.3.0"
@ -2126,12 +1850,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
[[package]]
name = "thiserror"
version = "1.0.30"
@ -2210,16 +1928,6 @@ dependencies = [
"syn",
]
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "tokio"
version = "1.17.0"
@ -2670,9 +2378,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.84"
version = "0.2.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b"
checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@ -2680,13 +2388,13 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.84"
version = "0.2.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9"
checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
@ -2695,9 +2403,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.84"
version = "0.2.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5"
checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -2705,9 +2413,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.84"
version = "0.2.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc"
dependencies = [
"proc-macro2",
"quote",
@ -2718,19 +2426,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.84"
version = "0.2.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
[[package]]
name = "web-sys"
version = "0.3.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
dependencies = [
"js-sys",
"wasm-bindgen",
]
checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2"
[[package]]
name = "winapi"
@ -2887,15 +2585,6 @@ version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "wyz"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
dependencies = [
"tap",
]
[[package]]
name = "xml-rs"
version = "0.8.4"

View File

@ -15,15 +15,12 @@ scip.workspace = true
serde.workspace = true
serde_json.workspace = true
syntect.workspace = true
protobuf.workspace = true
rustyline = "9.1.2"
base64 = "0.13.0"
sg-syntax = { path = "./crates/sg-syntax" }
scip-treesitter = { path = "./crates/scip-treesitter" }
scip-treesitter-languages = { path = "./crates/scip-treesitter-languages" }
scip-syntax = { path = "./crates/scip-syntax" }
# March 20, 2023 - Pinned explicitly with features that match the features
# required by rocket. Once bazel rules correctly roll up all the features,
# we can remove this, but until then, this works just fine for building
@ -41,12 +38,12 @@ members = [
"crates/scip-syntax",
"crates/scip-treesitter",
"crates/scip-treesitter-languages",
# "crates/ctags",
]
[workspace.dependencies]
anyhow = "1"
clap = { version = "4.1.11", features = [ "derive" ] }
itertools = "0.10.5"
rocket = { version = "0.5.0-rc.1", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
@ -60,11 +57,7 @@ scip = { git = "https://github.com/sourcegraph/scip", rev="3856df76147ca4b86df78
protobuf = "3"
[profile.release]
# Enabled debug symbols in release build, so if we have a crash
# we can inspect the coredump.
debug = true
[dev-dependencies]
criterion = { version = "0.4", features = [ "html_reports" ] }

View File

@ -0,0 +1,10 @@
[package]
name = "ctags"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
scip.workspace = true
anyhow.workspace = true

View File

@ -0,0 +1,92 @@
// use anyhow::Result;
// Some existing symbol structs
//
// zoekt
// type Symbol struct {
// Sym string
// Kind string
// Parent string
// ParentKind string
// }
//
// go-ctags
// type Entry struct {
// Name string
// Path string
// Line int
// Kind string
// Language string
// Parent string
// ParentKind string
// Pattern string
// Signature string
//
// FileLimited bool
// }
// LSP Symbol Kinds, could be fine for us to use now
// export namespace SymbolKind {
// export const File = 1;
// export const Module = 2;
// export const Namespace = 3;
// export const Package = 4;
// export const Class = 5;
// export const Method = 6;
// export const Property = 7;
// export const Field = 8;
// export const Constructor = 9;
// export const Enum = 10;
// export const Interface = 11;
// export const Function = 12;
// export const Variable = 13;
// export const Constant = 14;
// export const String = 15;
// export const Number = 16;
// export const Boolean = 17;
// export const Array = 18;
// export const Object = 19;
// export const Key = 20;
// export const Null = 21;
// export const EnumMember = 22;
// export const Struct = 23;
// export const Event = 24;
// export const Operator = 25;
// export const TypeParameter = 26;
// }
use scip::types::{Descriptor, Document};
#[derive(Debug)]
pub enum TagKind {
Function,
Class,
}
impl std::str::FromStr for TagKind {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"definition.function" => Ok(Self::Function),
"definition.type" => Ok(Self::Function),
_ => anyhow::bail!("unknown tag kind: {}", s),
}
}
}
#[derive(Debug)]
pub struct TagEntry {
pub descriptors: Vec<Descriptor>,
pub kind: TagKind,
pub parent: Option<Box<TagEntry>>,
pub line: usize,
// pub column: usize,
}
impl TagEntry {
pub fn from_document(document: Document) -> Vec<TagEntry> {
todo!("{:?}", document)
}
}

View File

@ -8,12 +8,9 @@ edition = "2021"
[dependencies]
anyhow.workspace = true
clap.workspace = true
itertools.workspace = true
protobuf.workspace = true
scip.workspace = true
tree-sitter.workspace = true
serde.workspace = true
serde_json.workspace = true
scip-macros = { path = "../scip-macros" }
scip-treesitter = { path = "../scip-treesitter" }
@ -22,5 +19,3 @@ scip-treesitter-languages = { path = "../scip-treesitter-languages" }
rustc-hash = "1.1.0"
walkdir = "2"
insta = "*"
once_cell = "1.17.1"
bitvec = "1.0.1"

View File

@ -1,11 +0,0 @@
; Make use of @local
(translation_unit (declaration (init_declarator declarator: (_) @descriptor.term)))
(enum_specifier name: (_) @descriptor.type body: (enumerator_list (enumerator name: (_) @descriptor.term)) @descriptor.scope)
(field_declaration declarator: [
(pointer_declarator (field_identifier) @descriptor.term)
(field_identifier) @descriptor.term
])
(function_definition (function_declarator declarator: (_) @descriptor.method))

View File

@ -1,11 +0,0 @@
(class_declaration name: (_) @descriptor.type) @scope
(interface_declaration name: (_) @descriptor.type) @scope
(enum_declaration name: (_) @descriptor.type) @scope
(namespace_declaration name: (_) @descriptor.type) @scope
(method_declaration name: (_) @descriptor.method)
(constructor_declaration name: (_) @descriptor.method)
(field_declaration (variable_declaration (variable_declarator (identifier) @descriptor.term)))
(property_declaration (identifier) @descriptor.term)
(enum_member_declaration name: (_) @descriptor.term)

View File

@ -1,10 +0,0 @@
; Make use of @local
(translation_unit (declaration (init_declarator declarator: (_) @descriptor.term)))
(namespace_definition name: (_) @descriptor.type body: (_) @descriptor.scope)
(class_specifier name: (_) @descriptor.type body: (_) @descriptor.scope)
(enum_specifier name: (_) @descriptor.type body: (enumerator_list (enumerator name: (_) @descriptor.term)) @descriptor.scope)
(field_declaration declarator: (_) @descriptor.term)
(function_definition (function_declarator declarator: (_) @descriptor.method))

View File

@ -1,4 +1,4 @@
(source_file (package_clause (package_identifier) @descriptor.namespace)) @scope
(source_file (package_clause (package_identifier) @descriptor.namespace) @scope)
(function_declaration
name: (identifier) @descriptor.method)
@ -15,9 +15,4 @@
(parameter_declaration type: (type_identifier) @descriptor.type))
name: (field_identifier) @descriptor.method)
(type_declaration (type_spec name: (type_identifier) @descriptor.type)) @scope
(field_declaration_list (field_declaration name: (_) @descriptor.term))
(const_spec name: (_) @descriptor.term)
(import_spec name: (_) @descriptor.term)
(type_declaration (type_spec name: (type_identifier) @descriptor.type))

View File

@ -1,16 +0,0 @@
(program
(package_declaration
(scoped_identifier)
@descriptor.namespace
)
) @scope
(class_declaration name: (_) @descriptor.type) @scope
(interface_declaration name: (_) @descriptor.type) @scope
(enum_declaration name: (_) @descriptor.type) @scope
(method_declaration name: (_) @descriptor.method) @local
(constructor_declaration name: (_) @descriptor.method) @local
(field_declaration (variable_declarator name: (_) @descriptor.term))
(enum_constant name: (_) @descriptor.term)

View File

@ -1,22 +0,0 @@
(namespace_import (identifier) @descriptor.term)
(named_imports
[
(import_specifier alias: (_) @descriptor.term)
(import_specifier name: (_) @descriptor.term !alias)
]
)
(function_declaration (identifier) @descriptor.method body: (_) @local)
(lexical_declaration (variable_declarator name: (identifier) @descriptor.term))
(variable_declaration (variable_declarator name: (identifier) @descriptor.term))
(class_declaration name: (_) @descriptor.type body: (_) @scope)
(class_declaration
(class_body
[
(method_definition name: (_) @descriptor.method body: (_) @local)
]
)
)
[(if_statement) (while_statement) (for_statement) (do_statement)] @local

View File

@ -1,14 +0,0 @@
(source_file
(package_header
(identifier)
@descriptor.namespace
)
) @scope
(function_declaration (simple_identifier) @descriptor.method) @local
(anonymous_function (_ (type_identifier) @descriptor.type . (type_identifier) @descriptor.method)) @local
(class_declaration (type_identifier) @descriptor.type)
(object_declaration (type_identifier) @descriptor.type)
(class_parameter (simple_identifier) @descriptor.term)
(enum_entry (simple_identifier) @descriptor.term)
(property_declaration (variable_declaration (simple_identifier) @descriptor.term))

View File

@ -1,8 +0,0 @@
(import_statement name: (_) @descriptor.term)
(import_from_statement name: (_) @descriptor.term)
(class_definition name: (_) @descriptor.type body: (_) @scope)
(function_definition name: (_) @descriptor.method body: (_) @local)
(expression_statement (assignment left: (identifier) @descriptor.term))
[(if_statement) (while_statement) (for_statement) (with_statement)] @local

View File

@ -1,4 +0,0 @@
(assignment left: [(identifier) (constant)] @descriptor.term)
(class name: (_) @descriptor.type) @scope
(method name: (_) @descriptor.method) @local
[(block) (unless)] @local

View File

@ -7,15 +7,16 @@
name: (_) @descriptor.type) @scope
(impl_item
trait: (_)? @descriptor.type
trait: (_) @descriptor.type
type: (_) @descriptor.type) @scope
;; TODO: @local to stop traversal
(function_signature_item
name: (identifier) @descriptor.method)
;; TODO: @local to stop traversal
(function_item
name: (identifier) @descriptor.method body: (_) @local)
name: (identifier) @descriptor.method)
(struct_item
name: (type_identifier) @descriptor.type) @scope

View File

@ -1,19 +0,0 @@
; TODO: Exclude functions in non-container blocks
(compilation_unit
(package_clause
(package_identifier)
@descriptor.namespace
)
) @scope
(compilation_unit (val_definition (identifier) @descriptor.term))
(compilation_unit (var_definition (identifier) @descriptor.term))
(template_body (val_definition (identifier) @descriptor.term))
(template_body (var_definition (identifier) @descriptor.term))
(function_definition (identifier) @descriptor.method)
(class_definition (identifier) @descriptor.type (template_body) @scope)
(object_definition (identifier) @descriptor.type (template_body) @scope)
(trait_definition (identifier) @descriptor.type (template_body) @scope)

View File

@ -1,42 +0,0 @@
(namespace_import (identifier) @descriptor.term)
(named_imports
[
(import_specifier alias: (_) @descriptor.term)
(import_specifier name: (_) @descriptor.term !alias)
]
)
(function_declaration (identifier) @descriptor.method body: (_) @local)
(lexical_declaration (variable_declarator name: (identifier) @descriptor.term))
(variable_declaration (variable_declarator name: (identifier) @descriptor.term))
(interface_declaration name: (_) @descriptor.type body: (_) @scope)
(interface_declaration
(object_type
[
(method_signature (property_identifier) @descriptor.method)
(property_signature (property_identifier) @descriptor.term)
]
)
)
(class_declaration name: (_) @descriptor.type body: (_) @scope)
(class_declaration
(class_body
[
(public_field_definition name: (_) @descriptor.term)
(method_definition name: (_) @descriptor.method body: (_) @local)
]
)
)
(enum_declaration name: (_) @descriptor.type body: (_) @scope)
(enum_declaration
(enum_body
(property_identifier) @descriptor.term
)
)
(module name: (string (string_fragment) @descriptor.namespace) body: (_) @scope)
[(if_statement) (while_statement) (for_statement) (do_statement)] @local

View File

@ -1,17 +0,0 @@
(Decl
(VarDecl
variable_type_function: (_)
@descriptor.term
(
(ErrorUnionExpr
(SuffixExpr
(ContainerDecl)
)
)
@scope
)?
)
)
(Decl (FnProto function: (_) @descriptor.method)) @local
(ContainerField field_member: (IDENTIFIER) @descriptor.term)

View File

@ -1,307 +0,0 @@
use std::{
collections::HashMap,
io::{BufRead, BufReader, BufWriter, Read, Write},
ops::Not,
path,
};
use anyhow::{Context, Result};
use itertools::intersperse;
use scip::types::{descriptor::Suffix, Descriptor};
use scip_treesitter_languages::parsers::BundledParser;
use serde::{Deserialize, Serialize};
use crate::{get_globals, globals::Scope};
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "command", rename_all = "kebab-case")]
pub enum Request {
GenerateTags { filename: String, size: usize },
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "_type", rename_all = "kebab-case")]
pub enum Reply<'a> {
Program {
name: String,
version: String,
},
Completed {
command: String,
},
Error {
message: String,
fatal: bool,
},
Tag {
name: String,
path: &'a str,
language: &'a str,
/// Starts at 1
line: usize,
kind: &'a str,
scope: Option<&'a str>,
// Can't find any uses of these. If someone reports a bug, we can support this
// scope_kind: Option<String>,
// signature: Option<String>,
},
}
impl<'a> Reply<'a> {
pub fn write<W: std::io::Write>(self, writer: &mut W) {
writer
.write_all(serde_json::to_string(&self).unwrap().as_bytes())
.unwrap();
writer.write_all("\n".as_bytes()).unwrap();
}
pub fn write_tag<W: std::io::Write>(
writer: &mut W,
scope: &Scope,
path: &'a str,
language: &'a str,
tag_scope: Option<&'a str>,
scope_deduplicator: &mut HashMap<String, ()>,
) {
let descriptors = &scope.descriptors;
let names = descriptors.iter().map(|d| d.name.as_str());
let name = intersperse(names, ".").collect::<String>();
let mut dedup = match tag_scope {
Some(ts) => vec![ts],
None => vec![],
};
dedup.push(&name);
let dedup = dedup.join(".");
if scope_deduplicator.contains_key(&dedup) {
return;
}
scope_deduplicator.insert(dedup, ());
let tag = Self::Tag {
name,
path,
language,
line: scope.scope_range.start_line as usize + 1,
kind: descriptors_to_kind(&scope.descriptors),
scope: tag_scope,
};
tag.write(writer);
}
}
fn descriptors_to_kind(descriptors: &[Descriptor]) -> &'static str {
match descriptors
.last()
.unwrap_or_default()
.suffix
.enum_value_or_default()
{
Suffix::Namespace => "namespace",
Suffix::Package => "package",
Suffix::Method => "method",
Suffix::Type => "type",
_ => "variable",
}
}
fn emit_tags_for_scope<W: std::io::Write>(
buf_writer: &mut BufWriter<W>,
path: &str,
parent_scopes: Vec<String>,
scope: &Scope,
language: &str,
scope_deduplicator: &mut HashMap<String, ()>,
) {
let curr_scopes = {
let mut curr_scopes = parent_scopes.clone();
for desc in &scope.descriptors {
curr_scopes.push(desc.name.clone());
}
curr_scopes
};
if !scope.descriptors.is_empty() {
let tag_scope = parent_scopes
.is_empty()
.not()
.then(|| parent_scopes.join("."));
let tag_scope = tag_scope.as_deref();
Reply::write_tag(
&mut *buf_writer,
scope,
path,
language,
tag_scope,
scope_deduplicator,
);
}
for subscope in &scope.children {
emit_tags_for_scope(
buf_writer,
path,
curr_scopes.clone(),
subscope,
language,
scope_deduplicator,
);
}
for global in &scope.globals {
let mut scope_name = curr_scopes.clone();
scope_name.extend(
global
.descriptors
.iter()
.take(global.descriptors.len() - 1)
.map(|d| d.name.clone()),
);
Reply::Tag {
name: global.descriptors.last().unwrap().name.clone(),
path,
language,
line: global.range.start_line as usize + 1,
kind: descriptors_to_kind(&global.descriptors),
scope: scope_name
.is_empty()
.not()
.then(|| scope_name.join("."))
.as_deref(),
}
.write(buf_writer);
}
}
pub fn generate_tags<W: std::io::Write>(
buf_writer: &mut BufWriter<W>,
filename: String,
file_data: &[u8],
) -> Option<()> {
let path = path::Path::new(&filename);
let extension = path.extension()?.to_str()?;
let filepath = path.file_name()?.to_str()?;
let parser = BundledParser::get_parser_from_extension(extension)?;
let (root_scope, _) = match get_globals(&parser, file_data)? {
Ok(vals) => vals,
Err(err) => {
// TODO: Not sure I want to keep this or not
#[cfg(debug_assertions)]
if true {
panic!("Could not parse file: {}", err);
}
return None;
}
};
let mut scope_deduplicator = HashMap::new();
emit_tags_for_scope(
buf_writer,
filepath,
vec![],
&root_scope,
// I don't believe the language name is actually used anywhere but we'll
// keep it to be compliant with the ctags spec
parser.get_language_name(),
&mut scope_deduplicator,
);
Some(())
}
pub fn ctags_runner<R: Read, W: Write>(
input: &mut BufReader<R>,
output: &mut std::io::BufWriter<W>,
) -> Result<()> {
Reply::Program {
name: "SCIP Ctags".to_string(),
version: "5.9.0".to_string(),
}
.write(output);
output.flush().unwrap();
loop {
let mut line = String::new();
input.read_line(&mut line)?;
if line.is_empty() {
break;
}
let request = serde_json::from_str::<Request>(&line);
let request = match request {
Ok(request) => request,
Err(_) => {
eprintln!("Could not parse request: {}", line);
continue;
}
};
match request {
Request::GenerateTags { filename, size } => {
let mut file_data = vec![0; size];
input
.read_exact(&mut file_data)
.expect("Could not fill file data exactly");
generate_tags(output, filename, &file_data);
}
}
Reply::Completed {
command: "generate-tags".to_string(),
}
.write(output);
output.flush().unwrap();
}
Ok(())
}
pub fn helper_execute_one_file(name: &str, contents: &str) -> Result<String> {
let command = format!(
r#"
{{ "command":"generate-tags","filename":"{}","size":{} }}
{}
"#,
name,
contents.len(),
contents
)
.trim()
.to_string();
let mut input = BufReader::new(command.as_bytes());
let mut output = BufWriter::new(Vec::new());
ctags_runner(&mut input, &mut output)?;
String::from_utf8(output.get_ref().to_vec()).context("Could not parse output")
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_ctags_runner_basic() -> Result<()> {
let file = r#"
fn main() {
println!("Hello, world!");
}
fn something() -> bool { true }
fn other() -> bool { false }
"#
.trim();
let output = helper_execute_one_file("main.rs", file)?;
insta::assert_snapshot!(output);
Ok(())
}
}

View File

@ -1,305 +0,0 @@
use anyhow::Result;
use bitvec::prelude::*;
use protobuf::Enum;
use scip::types::{Descriptor, Occurrence};
use scip_treesitter::types::PackedRange;
use crate::languages::TagConfiguration;
#[derive(Debug)]
pub struct Scope {
pub ident_range: PackedRange,
pub scope_range: PackedRange,
pub globals: Vec<Global>,
pub children: Vec<Scope>,
pub descriptors: Vec<Descriptor>,
}
#[derive(Debug)]
pub struct Global {
pub range: PackedRange,
pub descriptors: Vec<Descriptor>,
}
impl Scope {
pub fn insert_scope(&mut self, scope: Scope) {
if let Some(child) = self
.children
.iter_mut()
.find(|child| child.scope_range.contains(&scope.scope_range))
{
child.insert_scope(scope);
} else {
self.children.push(scope);
}
}
pub fn insert_global(&mut self, global: Global) {
if let Some(child) = self
.children
.iter_mut()
.find(|child| child.scope_range.contains(&global.range))
{
child.insert_global(global)
} else {
self.globals.push(global);
}
}
pub fn into_occurrences(
&mut self,
hint: usize,
base_descriptors: Vec<Descriptor>,
) -> Vec<Occurrence> {
let mut descriptor_stack = base_descriptors;
let mut occs = Vec::with_capacity(hint);
self.rec_into_occurrences(true, &mut occs, &mut descriptor_stack);
occs
}
fn rec_into_occurrences(
&self,
is_root: bool,
occurrences: &mut Vec<Occurrence>,
descriptor_stack: &mut Vec<Descriptor>,
) {
descriptor_stack.extend(self.descriptors.clone());
if !is_root {
occurrences.push(scip::types::Occurrence {
range: self.ident_range.to_vec(),
symbol: scip::symbol::format_symbol(scip::types::Symbol {
scheme: "scip-ctags".into(),
// TODO: Package?
package: None.into(),
descriptors: descriptor_stack.clone(),
..Default::default()
}),
symbol_roles: scip::types::SymbolRole::Definition.value(),
// TODO:
// syntax_kind: todo!(),
..Default::default()
});
}
for global in &self.globals {
let mut global_descriptors = descriptor_stack.clone();
global_descriptors.extend(global.descriptors.clone());
let symbol = scip::symbol::format_symbol(scip::types::Symbol {
scheme: "scip-ctags".into(),
// TODO: Package?
package: None.into(),
descriptors: global_descriptors,
..Default::default()
});
let symbol_roles = scip::types::SymbolRole::Definition.value();
occurrences.push(scip::types::Occurrence {
range: global.range.to_vec(),
symbol,
symbol_roles,
// TODO:
// syntax_kind: todo!(),
..Default::default()
});
}
self.children
.iter()
.for_each(|c| c.rec_into_occurrences(false, occurrences, descriptor_stack));
self.descriptors.iter().for_each(|_| {
descriptor_stack.pop();
});
}
}
pub fn parse_tree<'a>(
config: &TagConfiguration,
tree: &'a tree_sitter::Tree,
source_bytes: &'a [u8],
) -> Result<(Scope, usize)> {
let mut cursor = tree_sitter::QueryCursor::new();
let root_node = tree.root_node();
let capture_names = config.query.capture_names();
let mut scopes = vec![];
let mut globals = vec![];
let mut local_ranges = BitVec::<u8, Msb0>::repeat(false, source_bytes.len());
let matches = cursor.matches(&config.query, root_node, source_bytes);
for m in matches {
// eprintln!("\n==== NEW MATCH ====");
let mut node = None;
let mut scope = None;
let mut local_range = None;
let mut descriptors = vec![];
for capture in m.captures {
let capture_name = capture_names
.get(capture.index as usize)
.expect("capture indexes should always work");
if capture_name.starts_with("descriptor") {
descriptors.push((capture_name, capture.node.utf8_text(source_bytes)?));
node = Some(capture.node);
}
if capture_name.starts_with("scope") {
assert!(scope.is_none(), "declare only one scope per match");
scope = Some(capture);
}
if capture_name.starts_with("local") {
local_range = Some(capture.node.byte_range());
}
// eprintln!(
// "{}: {}",
// capture_name,
// capture.node.utf8_text(source_bytes).unwrap()
// );
}
match node {
Some(node) => {
if local_ranges[node.start_byte()] {
continue;
}
let descriptors = descriptors
.iter()
.map(|(capture, name)| {
crate::ts_scip::capture_name_to_descriptor(capture, name.to_string())
})
.collect();
// dbg!(node);
match scope {
Some(scope_ident) => scopes.push(Scope {
ident_range: node.into(),
scope_range: scope_ident.node.into(),
globals: vec![],
children: vec![],
descriptors,
}),
None => globals.push(Global {
range: node.into(),
descriptors,
}),
}
}
None => {
if local_range.is_none() {
panic!("there must always be at least one descriptor (except for @local)");
}
}
}
if let Some(local_range) = local_range {
local_ranges.get_mut(local_range).unwrap().fill(true);
}
}
let mut root = Scope {
ident_range: root_node.into(),
scope_range: root_node.into(),
globals: vec![],
children: vec![],
descriptors: vec![],
};
scopes.sort_by_key(|m| {
std::cmp::Reverse((
m.scope_range.start_line,
m.scope_range.end_line,
m.scope_range.start_col,
))
});
// Add all the scopes to our tree
while let Some(m) = scopes.pop() {
root.insert_scope(m);
}
while let Some(m) = globals.pop() {
root.insert_global(m);
}
Ok((root, globals.len()))
}
#[cfg(test)]
mod test {
use scip::types::Document;
use scip_treesitter::snapshot::dump_document;
use tree_sitter::Parser;
use super::*;
fn parse_file_for_lang(config: &TagConfiguration, source_code: &str) -> Result<Document> {
let source_bytes = source_code.as_bytes();
let mut parser = Parser::new();
parser.set_language(config.language).unwrap();
let tree = parser.parse(source_bytes, None).unwrap();
let mut occ = parse_tree(config, &tree, source_bytes)?;
let mut doc = Document::new();
doc.occurrences = occ.0.into_occurrences(occ.1, vec![]);
doc.symbols = doc
.occurrences
.iter()
.map(|o| scip::types::SymbolInformation {
symbol: o.symbol.clone(),
..Default::default()
})
.collect();
Ok(doc)
}
#[test]
fn test_can_parse_rust_tree() -> Result<()> {
let config = crate::languages::rust();
let source_code = include_str!("../testdata/scopes.rs");
let doc = parse_file_for_lang(config, source_code)?;
let dumped = dump_document(&doc, source_code)?;
insta::assert_snapshot!(dumped);
Ok(())
}
#[test]
fn test_can_parse_go_tree() -> Result<()> {
let config = crate::languages::go();
let source_code = include_str!("../testdata/example.go");
let doc = parse_file_for_lang(config, source_code)?;
// dbg!(doc);
let dumped = dump_document(&doc, source_code)?;
insta::assert_snapshot!(dumped);
Ok(())
}
#[test]
fn test_can_parse_go_internal_tree() -> Result<()> {
let config = crate::languages::go();
let source_code = include_str!("../testdata/internal_go.go");
let doc = parse_file_for_lang(config, source_code)?;
// dbg!(doc);
let dumped = dump_document(&doc, source_code)?;
insta::assert_snapshot!(dumped);
Ok(())
}
}

View File

@ -1,4 +1,3 @@
use once_cell::sync::OnceCell;
use scip_macros::include_scip_query;
use scip_treesitter_languages::parsers::BundledParser;
use tree_sitter::{Language, Parser, Query};
@ -6,227 +5,35 @@ use tree_sitter::{Language, Parser, Query};
pub struct TagConfiguration {
pub language: Language,
pub query: Query,
pub parser: Parser,
}
pub fn c() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
pub fn rust() -> TagConfiguration {
let language = BundledParser::Rust.get_language();
let query = include_scip_query!("rust", "scip-tags");
INSTANCE.get_or_init(|| {
let language = BundledParser::C.get_language();
let query = include_scip_query!("c", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
TagConfiguration {
language,
parser,
query: Query::new(language, query).unwrap(),
}
}
pub fn javascript() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
pub fn go() -> TagConfiguration {
let language = BundledParser::Go.get_language();
let query = include_scip_query!("go", "scip-tags");
INSTANCE.get_or_init(|| {
let language = BundledParser::Javascript.get_language();
let query = include_scip_query!("javascript", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn kotlin() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Kotlin.get_language();
let query = include_scip_query!("kotlin", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn ruby() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Ruby.get_language();
let query = include_scip_query!("ruby", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn python() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Python.get_language();
let query = include_scip_query!("python", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn cpp() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Cpp.get_language();
let query = include_scip_query!("cpp", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn typescript() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Typescript.get_language();
let query = include_scip_query!("typescript", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn scala() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Scala.get_language();
let query = include_scip_query!("scala", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn c_sharp() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::C_Sharp.get_language();
let query = include_scip_query!("c_sharp", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn java() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Java.get_language();
let query = include_scip_query!("java", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn rust() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Rust.get_language();
let query = include_scip_query!("rust", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn go() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Go.get_language();
let query = include_scip_query!("go", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
}
pub fn zig() -> &'static TagConfiguration {
static INSTANCE: OnceCell<TagConfiguration> = OnceCell::new();
INSTANCE.get_or_init(|| {
let language = BundledParser::Zig.get_language();
let query = include_scip_query!("zig", "scip-tags");
let mut parser = Parser::new();
parser.set_language(language).unwrap();
TagConfiguration {
language,
query: Query::new(language, query).unwrap(),
}
})
TagConfiguration {
language,
parser,
query: Query::new(language, query).unwrap(),
}
}
pub struct LocalConfiguration {
@ -263,25 +70,6 @@ fn perl_locals() -> LocalConfiguration {
}
}
pub fn get_tag_configuration(parser: &BundledParser) -> Option<&'static TagConfiguration> {
match parser {
BundledParser::C => Some(c()),
BundledParser::Javascript => Some(javascript()),
BundledParser::Kotlin => Some(kotlin()),
BundledParser::Ruby => Some(ruby()),
BundledParser::Python => Some(python()),
BundledParser::Cpp => Some(cpp()),
BundledParser::Typescript => Some(typescript()),
BundledParser::Scala => Some(scala()),
BundledParser::C_Sharp => Some(c_sharp()),
BundledParser::Java => Some(java()),
BundledParser::Rust => Some(rust()),
BundledParser::Go => Some(go()),
BundledParser::Zig => Some(zig()),
_ => None,
}
}
pub fn get_local_configuration(parser: BundledParser) -> Option<LocalConfiguration> {
match parser {
BundledParser::Go => Some(go_locals()),

View File

@ -1,75 +1,14 @@
use anyhow::Result;
use scip::types::Occurrence;
use scip_treesitter_languages::parsers::BundledParser;
use tree_sitter::Parser;
pub mod ctags;
pub mod globals;
pub mod languages;
pub mod locals;
pub mod matches;
pub mod ts_scip;
pub fn get_globals(
parser: &BundledParser,
source_bytes: &[u8],
) -> Option<Result<(globals::Scope, usize)>> {
let config = languages::get_tag_configuration(parser)?;
let mut parser = Parser::new();
parser.set_language(config.language).unwrap();
let tree = parser.parse(source_bytes, None).unwrap();
Some(globals::parse_tree(config, &tree, source_bytes))
}
pub fn get_locals(parser: BundledParser, source_bytes: &[u8]) -> Option<Result<Vec<Occurrence>>> {
let mut config = languages::get_local_configuration(parser)?;
let tree = config.parser.parse(source_bytes, None).unwrap();
Some(locals::parse_tree(&mut config, &tree, source_bytes))
}
#[macro_export]
macro_rules! generate_tags_and_snapshot {
($a:literal) => {{
let mut buffer = vec![0u8; 1024];
let mut buf_writer = BufWriter::new(&mut buffer);
generate_tags(&mut buf_writer, $a.to_string(), include_bytes!($a));
insta::assert_snapshot!(String::from_utf8_lossy(buf_writer.buffer()));
}};
}
#[cfg(test)]
mod test {
use std::io::BufWriter;
use crate::ctags::generate_tags;
#[test]
fn test_generate_ctags_go_globals() {
generate_tags_and_snapshot!("../testdata/go-globals.go");
}
#[test]
fn test_generate_ctags_empty_scope() {
generate_tags_and_snapshot!("../testdata/ctags-empty-scope.rs");
}
#[test]
fn test_generate_ctags_zig_globals() {
generate_tags_and_snapshot!("../testdata/globals.zig");
}
#[test]
fn test_generate_ctags_python_globals() {
generate_tags_and_snapshot!("../testdata/globals.py");
}
#[test]
fn test_generate_ctags_java_globals() {
generate_tags_and_snapshot!("../testdata/globals.java");
}
#[test]
fn test_generate_ctags_typescript_globals() {
generate_tags_and_snapshot!("../testdata/globals.ts");
}
}

View File

@ -5,15 +5,27 @@ use scip::{
symbol::format_symbol,
types::{Occurrence, Symbol},
};
use scip_treesitter::{prelude::*, types::PackedRange};
use scip_treesitter::prelude::*;
use tree_sitter::Node;
use crate::languages::LocalConfiguration;
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct ByteRange {
start: usize,
end: usize,
}
impl ByteRange {
pub fn contains(&self, other: &Self) -> bool {
self.start <= other.start && self.end >= other.end
}
}
#[derive(Debug)]
pub struct Scope<'a> {
pub scope: Node<'a>,
pub range: PackedRange,
pub range: ByteRange,
pub definitions: HashMap<&'a str, Definition<'a>>,
pub references: HashMap<&'a str, Vec<Reference<'a>>>,
pub children: Vec<Scope<'a>>,
@ -43,7 +55,10 @@ impl<'a> Scope<'a> {
pub fn new(scope: Node<'a>) -> Self {
Self {
scope,
range: scope.into(),
range: ByteRange {
start: scope.start_byte(),
end: scope.end_byte(),
},
definitions: HashMap::default(),
references: HashMap::default(),
children: vec![],
@ -87,10 +102,10 @@ impl<'a> Scope<'a> {
}
}
match self.children.binary_search_by_key(
&(reference.range.start_line, reference.range.start_col),
|r| (r.range.start_line, r.range.start_col),
) {
match self
.children
.binary_search_by_key(&reference.range.start, |r| r.range.start)
{
Ok(_) => {
// self.children[idx].insert_reference(reference);
todo!("I'm not sure what to do yet, think more now");
@ -140,8 +155,7 @@ impl<'a> Scope<'a> {
self.children.extend(child.children);
}
self.children
.sort_by_key(|s| (s.range.start_line, s.range.end_line, s.range.start_col));
self.children.sort_by_key(|s| s.range.start);
}
pub fn into_occurrences(&mut self, hint: usize) -> Vec<Occurrence> {
@ -155,7 +169,7 @@ impl<'a> Scope<'a> {
// We could probably make this a runtime option, where `self` has a `sorted` value
// that decides whether we need to or not. But on a huge file, this made no difference.
let mut values = self.definitions.values().collect::<Vec<_>>();
values.sort_by_key(|d| &d.range);
values.sort_by_key(|d| d.range.start);
for definition in values {
*id += 1;
@ -256,7 +270,7 @@ pub struct Definition<'a> {
pub group: &'a str,
pub identifier: &'a str,
pub node: Node<'a>,
pub range: PackedRange,
pub range: ByteRange,
pub scope_modifier: ScopeModifier,
}
@ -265,7 +279,7 @@ pub struct Reference<'a> {
pub group: &'a str,
pub identifier: &'a str,
pub node: Node<'a>,
pub range: PackedRange,
pub range: ByteRange,
}
pub fn parse_tree<'a>(
@ -342,7 +356,10 @@ pub fn parse_tree<'a>(
let scope_modifier = scope_modifier.unwrap_or_default();
definitions.push(Definition {
range: node.into(),
range: ByteRange {
start: node.start_byte(),
end: node.end_byte(),
},
group,
identifier,
node,
@ -355,7 +372,10 @@ pub fn parse_tree<'a>(
};
references.push(Reference {
range: node.into(),
range: ByteRange {
start: node.start_byte(),
end: node.end_byte(),
},
group,
identifier,
node,
@ -375,9 +395,8 @@ pub fn parse_tree<'a>(
// Sort smallest to largest, so we can pop off the end of the list for the largest, first scope
scopes.sort_by_key(|m| {
(
std::cmp::Reverse(m.range.start_line),
m.range.end_line - m.range.start_line,
m.range.end_col - m.range.start_col,
std::cmp::Reverse(m.range.start),
m.range.end - m.range.start,
)
});

View File

@ -0,0 +1,345 @@
use anyhow::Result;
use protobuf::Enum;
use scip::types::Descriptor;
use scip_treesitter::prelude::*;
use tree_sitter::Node;
use crate::languages::TagConfiguration;
#[derive(Debug)]
pub struct Root<'a> {
pub root: Node<'a>,
pub children: Vec<Matched<'a>>,
}
// #[derive(Debug)]
// pub struct Namespace {}
pub struct Scope<'a> {
pub definer: Node<'a>,
pub scope: Node<'a>,
pub descriptors: Vec<Descriptor>,
pub children: Vec<Matched<'a>>,
}
impl<'a> std::fmt::Debug for Scope<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let descriptors = dbg_format_descriptors(&self.descriptors);
write!(
f,
"({}, {}, {:?}) -> {:?}",
self.scope.kind(),
self.scope.start_position(),
descriptors,
self.children
)
}
}
pub struct Global<'a> {
pub node: Node<'a>,
pub descriptors: Vec<Descriptor>,
}
impl<'a> std::fmt::Debug for Global<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let descriptors = dbg_format_descriptors(&self.descriptors);
write!(
f,
"({}, {}, {:?})",
self.node.kind(),
self.node.start_position(),
descriptors
)
}
}
#[derive(Debug)]
// TODO: Root as it's own type?
pub enum Matched<'a> {
/// The root node of a file
Root(Root<'a>),
/// Does not generate a definition, simply a place ot add new descriptors
/// TODO: Haven't done this one for real yet
// Namespace(Namespace),
/// Generates a new definition, and is itself a place to add additional descriptors
Scope(Scope<'a>),
/// Generates a new definition, but does not generate a new scope
Global(Global<'a>),
}
impl<'a> ContainsNode for Matched<'a> {
fn contains_node(&self, node: &Node) -> bool {
self.node().contains_node(node)
}
}
impl<'a> Matched<'a> {
pub fn node(&self) -> &Node<'a> {
match self {
Matched::Root(m) => &m.root,
Matched::Scope(m) => &m.scope,
Matched::Global(m) => &m.node,
}
}
// pub fn children(&self) -> &Vec<Matched<'a>> {
// match self {
// Matched::Root(m) => &m.children,
// Matched::Scope(s) => &s.children,
// Matched::Global(_) => todo!(),
// }
// }
pub fn insert(&mut self, m: Matched<'a>) {
match self {
Matched::Root(root) => {
if let Some(child) = root
.children
.iter_mut()
.find(|child| child.contains_node(m.node()))
{
child.insert(m);
} else {
root.children.push(m);
}
}
Matched::Scope(scope) => {
if let Some(child) = scope
.children
.iter_mut()
.find(|child| child.contains_node(m.node()))
{
child.insert(m);
} else {
scope.children.push(m);
}
}
Matched::Global(_) => unreachable!(),
}
}
pub fn into_occurences(&self) -> Vec<scip::types::Occurrence> {
self.rec_into_occurrences(&[])
}
// TODO: Could we use a dequeue for this to pop on and off quickly?
// TODO: Could we use a way to format the symbol w/out all the preamble?
// Perhaps just a "format_descriptors" function in the lib, that I didn't expose beforehand
fn rec_into_occurrences(&self, descriptors: &[Descriptor]) -> Vec<scip::types::Occurrence> {
match self {
Matched::Root(root) => {
assert!(descriptors.is_empty(), "root should not have descriptors");
root.children
.iter()
.flat_map(|c| c.rec_into_occurrences(descriptors))
.collect()
}
Matched::Scope(scope) => {
let mut these_descriptors = descriptors.to_vec();
these_descriptors.extend(scope.descriptors.iter().cloned());
let symbol = scip::symbol::format_symbol(scip::types::Symbol {
scheme: "scip-ctags".into(),
// TODO: Package?
package: None.into(),
descriptors: these_descriptors,
..Default::default()
});
let symbol_roles = scip::types::SymbolRole::Definition.value();
let mut children = vec![scip::types::Occurrence {
range: vec![
scope.definer.start_position().row as i32,
scope.definer.start_position().column as i32,
scope.definer.end_position().column as i32,
],
symbol,
symbol_roles,
// TODO:
// syntax_kind: todo!(),
..Default::default()
}];
children.extend(scope.children.iter().flat_map(|c| {
let mut descriptors = descriptors.to_vec();
descriptors.extend(scope.descriptors.iter().cloned());
c.rec_into_occurrences(&descriptors)
}));
children
}
Matched::Global(global) => {
let mut these_descriptors = descriptors.to_vec();
these_descriptors.extend(global.descriptors.iter().cloned());
let symbol = scip::symbol::format_symbol(scip::types::Symbol {
scheme: "scip-ctags".into(),
// TODO: Package?
package: None.into(),
descriptors: these_descriptors,
..Default::default()
});
let symbol_roles = scip::types::SymbolRole::Definition.value();
vec![scip::types::Occurrence {
range: vec![
global.node.start_position().row as i32,
global.node.start_position().column as i32,
global.node.end_position().column as i32,
],
symbol,
symbol_roles,
// TODO:
// syntax_kind: todo!(),
..Default::default()
}]
}
}
}
}
pub fn parse_tree<'a>(
config: &mut TagConfiguration,
tree: &'a tree_sitter::Tree,
source_bytes: &'a [u8],
) -> Result<Vec<scip::types::Occurrence>> {
let mut cursor = tree_sitter::QueryCursor::new();
let root_node = tree.root_node();
let capture_names = config.query.capture_names();
let mut matched = vec![];
for m in cursor.matches(&config.query, root_node, source_bytes) {
println!("\n==== NEW MATCH ====");
let mut node = None;
let mut scope = None;
let mut descriptors = vec![];
for capture in m.captures {
let capture_name = capture_names
.get(capture.index as usize)
.expect("capture indexes should always work");
if capture_name.starts_with("descriptor") {
descriptors.push((capture_name, capture.node.utf8_text(source_bytes)?));
node = Some(capture.node);
}
if capture_name.starts_with("scope") {
assert!(scope.is_none(), "declare only one scope per match");
scope = Some(capture);
}
println!(
"{}: {}",
capture_name,
capture.node.utf8_text(source_bytes).unwrap()
);
}
let descriptors = descriptors
.into_iter()
.map(|(capture, name)| {
crate::ts_scip::capture_name_to_descriptor(capture, name.to_string())
})
.collect::<Vec<_>>();
let node = node.expect("there must always be at least one descriptor");
dbg!(node);
matched.push(match scope {
Some(scope) => Matched::Scope(Scope {
definer: node,
scope: scope.node,
descriptors,
children: vec![],
}),
None => Matched::Global(Global { node, descriptors }),
})
}
dbg!(&matched);
let mut root = Matched::Root(Root {
root: root_node,
children: vec![],
});
matched.sort_by_key(|m| {
let node = m.node();
node.end_byte() - node.start_byte()
});
while let Some(m) = matched.pop() {
root.insert(m);
}
dbg!(&root);
let tags = root.into_occurences();
Ok(dbg!(tags))
}
fn dbg_format_descriptors(descriptors: &[Descriptor]) -> Vec<String> {
descriptors
.iter()
.map(|d| format!("{} ({:?})", d.name, d.suffix))
.collect::<Vec<_>>()
}
#[cfg(test)]
mod test {
use scip::types::Document;
use scip_treesitter::snapshot::dump_document;
use super::*;
fn parse_file_for_lang(config: &mut TagConfiguration, source_code: &str) -> Result<Document> {
let source_bytes = source_code.as_bytes();
let tree = config.parser.parse(source_bytes, None).unwrap();
let occ = parse_tree(config, &tree, source_bytes)?;
let mut doc = Document::new();
doc.occurrences = occ;
doc.symbols = doc
.occurrences
.iter()
.map(|o| scip::types::SymbolInformation {
symbol: o.symbol.clone(),
..Default::default()
})
.collect();
Ok(doc)
}
#[test]
fn test_can_parse_rust_tree() -> Result<()> {
let mut config = crate::languages::rust();
let source_code = include_str!("../testdata/scopes.rs");
let doc = parse_file_for_lang(&mut config, source_code)?;
let dumped = dump_document(&doc, source_code)?;
insta::assert_snapshot!(dumped);
Ok(())
}
#[test]
fn test_can_parse_go_tree() -> Result<()> {
let mut config = crate::languages::go();
let source_code = include_str!("../testdata/example.go");
let doc = dbg!(parse_file_for_lang(&mut config, source_code)?);
let dumped = dump_document(&doc, source_code)?;
insta::assert_snapshot!(dumped);
Ok(())
}
}

View File

@ -0,0 +1,45 @@
---
source: src/locals.rs
assertion_line: 469
expression: dumped
---
package example
// ^^^^^^^ definition local 1
import (
f "fmt"
// ^ definition local 2
"github.com/sourcegraph/"
)
func Something() {
// ^^^^^^^^^ definition local 3
y := ", world"
// ^ definition local 5
f.Println("hello", y)
// ^ reference local 2
// ^ reference local 5
}
func Another() {
// ^^^^^^^ definition local 4
Something()
// ^^^^^^^^^ reference local 3
if true {
x := true
// ^ definition local 6
}
if true {
x := true
// ^ definition local 7
if true {
x := true
// ^ definition local 8
}
}
if true {
x := true
// ^ definition local 9
}
}

View File

@ -0,0 +1,31 @@
---
source: src/locals.rs
assertion_line: 463
expression: dumped
---
package main
// ^^^^ definition local 1
func main() {
// ^^^^ reference local 1
local := true
// ^^^^^ definition local 3
something := func(local int) int {
// ^^^^^^^^^ definition local 4
// ^^^^^ definition local 5
return local
// ^^^^^ reference local 5
}
println(local, something)
// ^^^^^ reference local 3
// ^^^^^^^^^ reference local 4
}
func Another(local int) int {
// ^^^^^^^ definition local 2
// ^^^^^ definition local 6
return local
// ^^^^^ reference local 6
}

View File

@ -0,0 +1,42 @@
---
source: src/locals.rs
assertion_line: 502
expression: dumped
---
package main
// ^^^^ definition local 1
func main() {
// ^^^^ reference local 1
local := 5
// ^^^^^ definition local 2
something := func(unrelated int) int {
// ^^^^^^^^^ definition local 3
// ^^^^^^^^^ definition local 4
superNested := func(deeplyNested int) int {
// ^^^^^^^^^^^ definition local 5
// ^^^^^^^^^^^^ definition local 7
return local + unrelated + deeplyNested
// ^^^^^ reference local 2
// ^^^^^^^^^ reference local 4
// ^^^^^^^^^^^^ reference local 7
}
overwriteName := func(local int) int {
// ^^^^^^^^^^^^^ definition local 6
// ^^^^^ definition local 8
return local + unrelated
// ^^^^^ reference local 8
// ^^^^^^^^^ reference local 4
}
return superNested(1) + overwriteName(1)
// ^^^^^^^^^^^ reference local 5
// ^^^^^^^^^^^^^ reference local 6
}
println(local, something)
// ^^^^^ reference local 2
// ^^^^^^^^^ reference local 3
}

View File

@ -0,0 +1,29 @@
---
source: src/matches.rs
assertion_line: 341
expression: dumped
---
package example
// ^^^^^^^ definition scip-ctags example/
import (
f "fmt"
)
func Something() {
// ^^^^^^^^^ definition scip-ctags Something().
x := true
f.Println(x)
}
func Another() float64 { return 5 / 3 }
// ^^^^^^^ definition scip-ctags Another().
type MyThing struct{}
// ^^^^^^^ definition scip-ctags MyThing#
func (m *MyThing) DoSomething() {}
// ^^^^^^^^^^^ definition scip-ctags MyThing#DoSomething().
func (m MyThing) DoSomethingElse() {}
// ^^^^^^^^^^^^^^^ definition scip-ctags MyThing#DoSomethingElse().

View File

@ -0,0 +1,34 @@
---
source: src/matches.rs
assertion_line: 334
expression: dumped
---
pub trait Tag {
// ^^^ definition scip-ctags Tag#
// This is a pretty big thing
// And some more things here
fn name(&self) -> &str;
// ^^^^ definition scip-ctags Tag#name().
}
mod namespace {
// ^^^^^^^^^ definition scip-ctags namespace/
mod nested {
// ^^^^^^ definition scip-ctags namespace/nested/
mod even_more_nested {
// ^^^^^^^^^^^^^^^^ definition scip-ctags namespace/nested/even_more_nested/
pub struct CoolStruct {}
// ^^^^^^^^^^ definition scip-ctags namespace/nested/even_more_nested/CoolStruct#
impl Tag for CoolStruct {
// ^^^^^^^^^^ definition scip-ctags namespace/nested/even_more_nested/Tag#CoolStruct#
fn name(&self) -> &str {}
// ^^^^ definition scip-ctags namespace/nested/even_more_nested/Tag#CoolStruct#name().
}
}
}
}
fn something() {}
// ^^^^^^^^^ definition scip-ctags something().

View File

@ -1,10 +0,0 @@
---
source: crates/scip-syntax/src/ctags.rs
expression: output
---
{"_type":"program","name":"SCIP Ctags","version":"5.9.0"}
{"_type":"tag","name":"other","path":"main.rs","language":"rust","line":6,"kind":"method","scope":null}
{"_type":"tag","name":"something","path":"main.rs","language":"rust","line":5,"kind":"method","scope":null}
{"_type":"tag","name":"main","path":"main.rs","language":"rust","line":1,"kind":"method","scope":null}
{"_type":"completed","command":"generate-tags"}

View File

@ -1,41 +0,0 @@
---
source: crates/scip-syntax/src/globals.rs
expression: dumped
---
package memo
// ^^^^ definition scip-ctags memo/
import "sync"
// MemoizedConstructorWithArg wraps a function returning taking a
// single argument value and returning a value and an error, memoizing
// its result. Multiple calls to Init will result in the underlying
// constructor being called once. The arguments to the call will be the
// first call to occur. All callers will receive the same return values.
type MemoizedConstructorWithArg[A, T any] struct {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^ definition scip-ctags memo/MemoizedConstructorWithArg#
ctor func(A) (T, error)
// ^^^^ definition scip-ctags memo/MemoizedConstructorWithArg#ctor.
value T
// ^^^^^ definition scip-ctags memo/MemoizedConstructorWithArg#value.
err error
// ^^^ definition scip-ctags memo/MemoizedConstructorWithArg#err.
once sync.Once
// ^^^^ definition scip-ctags memo/MemoizedConstructorWithArg#once.
}
// NewMemoizedConstructor memoizes the given constructor
func NewMemoizedConstructorWithArg[A, T any](ctor func(A) (T, error)) *MemoizedConstructorWithArg[A, T] {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition scip-ctags memo/NewMemoizedConstructorWithArg().
return &MemoizedConstructorWithArg[A, T]{ctor: ctor}
}
// Init ensures that the given constructor has been called exactly
// once, then returns the constructor's result value and error.
func (m *MemoizedConstructorWithArg[A, T]) Init(arg A) (T, error) {
// ^^^^ definition scip-ctags memo/T#Init().
// ^^^^ definition scip-ctags memo/A#Init().
m.once.Do(func() { m.value, m.err = m.ctor(arg) })
return m.value, m.err
}

View File

@ -1,29 +0,0 @@
---
source: crates/scip-syntax/src/globals.rs
expression: dumped
---
package example
// ^^^^^^^ definition scip-ctags example/
import (
f "fmt"
// ^ definition scip-ctags example/f.
)
func Something() {
// ^^^^^^^^^ definition scip-ctags example/Something().
x := true
f.Println(x)
}
func Another() float64 { return 5 / 3 }
// ^^^^^^^ definition scip-ctags example/Another().
type MyThing struct{}
// ^^^^^^^ definition scip-ctags example/MyThing#
func (m *MyThing) DoSomething() {}
// ^^^^^^^^^^^ definition scip-ctags example/MyThing#DoSomething().
func (m MyThing) DoSomethingElse() {}
// ^^^^^^^^^^^^^^^ definition scip-ctags example/MyThing#DoSomethingElse().

View File

@ -0,0 +1,29 @@
---
source: crates/scip-syntax/src/matches.rs
assertion_line: 341
expression: dumped
---
package example
// ^^^^^^^ definition scip-ctags example/
import (
f "fmt"
)
func Something() {
// ^^^^^^^^^ definition scip-ctags Something().
x := true
f.Println(x)
}
func Another() float64 { return 5 / 3 }
// ^^^^^^^ definition scip-ctags Another().
type MyThing struct{}
// ^^^^^^^ definition scip-ctags MyThing#
func (m *MyThing) DoSomething() {}
// ^^^^^^^^^^^ definition scip-ctags MyThing#DoSomething().
func (m MyThing) DoSomethingElse() {}
// ^^^^^^^^^^^^^^^ definition scip-ctags MyThing#DoSomethingElse().

View File

@ -1,6 +1,6 @@
---
source: crates/scip-syntax/src/globals.rs
assertion_line: 318
source: crates/scip-syntax/src/matches.rs
assertion_line: 329
expression: dumped
---
pub trait Tag {

View File

@ -1,10 +0,0 @@
---
source: crates/scip-syntax/src/lib.rs
expression: "String::from_utf8_lossy(buf_writer.buffer())"
---
{"_type":"tag","name":"Arguments","path":"ctags-empty-scope.rs","language":"rust","line":10,"kind":"type","scope":null}
{"_type":"tag","name":"ParseTiming","path":"ctags-empty-scope.rs","language":"rust","line":15,"kind":"type","scope":null}
{"_type":"tag","name":"main","path":"ctags-empty-scope.rs","language":"rust","line":28,"kind":"method","scope":null}
{"_type":"tag","name":"measure_parsing","path":"ctags-empty-scope.rs","language":"rust","line":24,"kind":"method","scope":null}
{"_type":"tag","name":"parse_files","path":"ctags-empty-scope.rs","language":"rust","line":20,"kind":"method","scope":null}

View File

@ -1,12 +0,0 @@
---
source: crates/scip-syntax/src/lib.rs
expression: "String::from_utf8_lossy(buf_writer.buffer())"
---
{"_type":"tag","name":"multierror","path":"go-globals.go","language":"go","line":1,"kind":"namespace","scope":null}
{"_type":"tag","name":"Group","path":"go-globals.go","language":"go","line":7,"kind":"type","scope":"multierror"}
{"_type":"tag","name":"wg","path":"go-globals.go","language":"go","line":10,"kind":"variable","scope":"multierror.Group"}
{"_type":"tag","name":"err","path":"go-globals.go","language":"go","line":9,"kind":"variable","scope":"multierror.Group"}
{"_type":"tag","name":"mutex","path":"go-globals.go","language":"go","line":8,"kind":"variable","scope":"multierror.Group"}
{"_type":"tag","name":"Wait","path":"go-globals.go","language":"go","line":33,"kind":"method","scope":"multierror.Group"}
{"_type":"tag","name":"Go","path":"go-globals.go","language":"go","line":17,"kind":"method","scope":"multierror.Group"}

View File

@ -1,31 +0,0 @@
---
source: crates/scip-syntax/src/lib.rs
expression: "String::from_utf8_lossy(buf_writer.buffer())"
---
{"_type":"tag","name":"globals","path":"globals.java","language":"java","line":1,"kind":"type","scope":null}
{"_type":"tag","name":"ClassInAClass","path":"globals.java","language":"java","line":18,"kind":"type","scope":"globals"}
{"_type":"tag","name":"Enum","path":"globals.java","language":"java","line":21,"kind":"type","scope":"globals.ClassInAClass"}
{"_type":"tag","name":"terms","path":"globals.java","language":"java","line":27,"kind":"variable","scope":"globals.ClassInAClass.Enum"}
{"_type":"tag","name":"as","path":"globals.java","language":"java","line":26,"kind":"variable","scope":"globals.ClassInAClass.Enum"}
{"_type":"tag","name":"recognized","path":"globals.java","language":"java","line":25,"kind":"variable","scope":"globals.ClassInAClass.Enum"}
{"_type":"tag","name":"be","path":"globals.java","language":"java","line":24,"kind":"variable","scope":"globals.ClassInAClass.Enum"}
{"_type":"tag","name":"should","path":"globals.java","language":"java","line":23,"kind":"variable","scope":"globals.ClassInAClass.Enum"}
{"_type":"tag","name":"these","path":"globals.java","language":"java","line":22,"kind":"variable","scope":"globals.ClassInAClass.Enum"}
{"_type":"tag","name":"Goated","path":"globals.java","language":"java","line":30,"kind":"type","scope":"globals.ClassInAClass"}
{"_type":"tag","name":"withTheSauce","path":"globals.java","language":"java","line":31,"kind":"method","scope":"globals.ClassInAClass.Goated"}
{"_type":"tag","name":"myCoolMethod","path":"globals.java","language":"java","line":34,"kind":"method","scope":"globals.ClassInAClass"}
{"_type":"tag","name":"classy","path":"globals.java","language":"java","line":19,"kind":"variable","scope":"globals.ClassInAClass"}
{"_type":"tag","name":"COOLEST_STRING","path":"globals.java","language":"java","line":16,"kind":"variable","scope":"globals"}
{"_type":"tag","name":"method6","path":"globals.java","language":"java","line":14,"kind":"method","scope":"globals"}
{"_type":"tag","name":"method5","path":"globals.java","language":"java","line":13,"kind":"method","scope":"globals"}
{"_type":"tag","name":"method4","path":"globals.java","language":"java","line":12,"kind":"method","scope":"globals"}
{"_type":"tag","name":"method3","path":"globals.java","language":"java","line":11,"kind":"method","scope":"globals"}
{"_type":"tag","name":"method2","path":"globals.java","language":"java","line":10,"kind":"method","scope":"globals"}
{"_type":"tag","name":"method1","path":"globals.java","language":"java","line":9,"kind":"method","scope":"globals"}
{"_type":"tag","name":"field6","path":"globals.java","language":"java","line":7,"kind":"variable","scope":"globals"}
{"_type":"tag","name":"field5","path":"globals.java","language":"java","line":6,"kind":"variable","scope":"globals"}
{"_type":"tag","name":"field4","path":"globals.java","language":"java","line":5,"kind":"variable","scope":"globals"}
{"_type":"tag","name":"field3","path":"globals.java","language":"java","line":4,"kind":"variable","scope":"globals"}
{"_type":"tag","name":"field2","path":"globals.java","language":"java","line":3,"kind":"variable","scope":"globals"}
{"_type":"tag","name":"field1","path":"globals.java","language":"java","line":2,"kind":"variable","scope":"globals"}

View File

@ -1,10 +0,0 @@
---
source: crates/scip-syntax/src/lib.rs
expression: "String::from_utf8_lossy(buf_writer.buffer())"
---
{"_type":"tag","name":"Bruh","path":"globals.py","language":"python","line":6,"kind":"type","scope":null}
{"_type":"tag","name":"dab","path":"globals.py","language":"python","line":11,"kind":"method","scope":"Bruh"}
{"_type":"tag","name":"__init__","path":"globals.py","language":"python","line":8,"kind":"method","scope":"Bruh"}
{"_type":"tag","name":"a","path":"globals.py","language":"python","line":6,"kind":"variable","scope":"Bruh"}
{"_type":"tag","name":"bruh","path":"globals.py","language":"python","line":3,"kind":"variable","scope":null}

View File

@ -1,22 +0,0 @@
---
source: crates/scip-syntax/src/lib.rs
expression: "String::from_utf8_lossy(buf_writer.buffer())"
---
{"_type":"tag","name":"MyClass","path":"globals.ts","language":"typescript","line":1,"kind":"type","scope":null}
{"_type":"tag","name":"also_private_method","path":"globals.ts","language":"typescript","line":8,"kind":"method","scope":"MyClass"}
{"_type":"tag","name":"#private_method","path":"globals.ts","language":"typescript","line":7,"kind":"method","scope":"MyClass"}
{"_type":"tag","name":"public_method","path":"globals.ts","language":"typescript","line":6,"kind":"method","scope":"MyClass"}
{"_type":"tag","name":"also_private_field","path":"globals.ts","language":"typescript","line":4,"kind":"variable","scope":"MyClass"}
{"_type":"tag","name":"#private_field","path":"globals.ts","language":"typescript","line":3,"kind":"variable","scope":"MyClass"}
{"_type":"tag","name":"public_field","path":"globals.ts","language":"typescript","line":2,"kind":"variable","scope":"MyClass"}
{"_type":"tag","name":"MyInterface","path":"globals.ts","language":"typescript","line":11,"kind":"type","scope":null}
{"_type":"tag","name":"sayBruh","path":"globals.ts","language":"typescript","line":13,"kind":"method","scope":"MyInterface"}
{"_type":"tag","name":"bruh","path":"globals.ts","language":"typescript","line":12,"kind":"variable","scope":"MyInterface"}
{"_type":"tag","name":"MyEnum","path":"globals.ts","language":"typescript","line":16,"kind":"type","scope":null}
{"_type":"tag","name":"go","path":"globals.ts","language":"typescript","line":19,"kind":"variable","scope":"MyEnum"}
{"_type":"tag","name":"rust","path":"globals.ts","language":"typescript","line":18,"kind":"variable","scope":"MyEnum"}
{"_type":"tag","name":"zig","path":"globals.ts","language":"typescript","line":17,"kind":"variable","scope":"MyEnum"}
{"_type":"tag","name":"func","path":"globals.ts","language":"typescript","line":25,"kind":"method","scope":null}
{"_type":"tag","name":"global2","path":"globals.ts","language":"typescript","line":23,"kind":"variable","scope":null}
{"_type":"tag","name":"global1","path":"globals.ts","language":"typescript","line":22,"kind":"variable","scope":null}

View File

@ -1,27 +0,0 @@
---
source: crates/scip-syntax/src/lib.rs
expression: "String::from_utf8_lossy(buf_writer.buffer())"
---
{"_type":"tag","name":"Bruh","path":"globals.zig","language":"zig","line":1,"kind":"variable","scope":null}
{"_type":"tag","name":"init","path":"globals.zig","language":"zig","line":4,"kind":"method","scope":"Bruh"}
{"_type":"tag","name":"zig_is_cool","path":"globals.zig","language":"zig","line":2,"kind":"variable","scope":"Bruh"}
{"_type":"tag","name":"MyUnion","path":"globals.zig","language":"zig","line":10,"kind":"variable","scope":null}
{"_type":"tag","name":"init","path":"globals.zig","language":"zig","line":16,"kind":"method","scope":"MyUnion"}
{"_type":"tag","name":"b","path":"globals.zig","language":"zig","line":14,"kind":"variable","scope":"MyUnion"}
{"_type":"tag","name":"a","path":"globals.zig","language":"zig","line":13,"kind":"variable","scope":"MyUnion"}
{"_type":"tag","name":"decl","path":"globals.zig","language":"zig","line":11,"kind":"variable","scope":"MyUnion"}
{"_type":"tag","name":"MyEnum","path":"globals.zig","language":"zig","line":19,"kind":"variable","scope":null}
{"_type":"tag","name":"init","path":"globals.zig","language":"zig","line":25,"kind":"method","scope":"MyEnum"}
{"_type":"tag","name":"b","path":"globals.zig","language":"zig","line":23,"kind":"variable","scope":"MyEnum"}
{"_type":"tag","name":"a","path":"globals.zig","language":"zig","line":22,"kind":"variable","scope":"MyEnum"}
{"_type":"tag","name":"decl","path":"globals.zig","language":"zig","line":20,"kind":"variable","scope":"MyEnum"}
{"_type":"tag","name":"MyUnionEnum","path":"globals.zig","language":"zig","line":28,"kind":"variable","scope":null}
{"_type":"tag","name":"init","path":"globals.zig","language":"zig","line":34,"kind":"method","scope":"MyUnionEnum"}
{"_type":"tag","name":"b","path":"globals.zig","language":"zig","line":32,"kind":"variable","scope":"MyUnionEnum"}
{"_type":"tag","name":"a","path":"globals.zig","language":"zig","line":31,"kind":"variable","scope":"MyUnionEnum"}
{"_type":"tag","name":"decl","path":"globals.zig","language":"zig","line":29,"kind":"variable","scope":"MyUnionEnum"}
{"_type":"tag","name":"Ahh","path":"globals.zig","language":"zig","line":37,"kind":"variable","scope":null}
{"_type":"tag","name":"opaqueFn","path":"globals.zig","language":"zig","line":38,"kind":"method","scope":"Ahh"}
{"_type":"tag","name":"complex","path":"globals.zig","language":"zig","line":47,"kind":"method","scope":null}
{"_type":"tag","name":"bruh","path":"globals.zig","language":"zig","line":41,"kind":"method","scope":null}

View File

@ -6,7 +6,6 @@ pub fn capture_name_to_descriptor(capture: &str, name: String) -> Descriptor {
"descriptor.method" => Suffix::Method,
"descriptor.namespace" => Suffix::Namespace,
"descriptor.type" => Suffix::Type,
"descriptor.term" => Suffix::Term,
// TODO: Should consider moving to result here.
_ => Suffix::UnspecifiedSuffix,

View File

@ -1,30 +0,0 @@
use std::{path::Path, time::Instant};
use clap::Parser;
use scip_syntax::locals::parse_tree;
use scip_treesitter_languages::parsers::BundledParser;
use walkdir::WalkDir;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Arguments {
/// Root directory to run local navigation over
root_dir: String,
}
struct ParseTiming {
pub filepath: String,
pub duration: std::time::Duration,
}
fn parse_files(dir: &Path) -> Vec<ParseTiming> {
// TODO
}
fn measure_parsing() {
// TODO
}
fn main() {
// TODO
}

View File

@ -1,39 +0,0 @@
public class globals {
private static int field1;
protected static int field2;
public static int field3;
private int field4;
protected int field5;
public int field6;
private static void method1() {}
protected static void method2() {}
public static void method3() {}
private void method4() {}
protected void method5() {}
public void method6() {}
public static final String COOLEST_STRING = "probably this one";
public class ClassInAClass {
boolean classy = true;
public static enum Enum {
these,
should,
be,
recognized,
as,
terms
}
public interface Goated {
boolean withTheSauce();
}
public void myCoolMethod() {
class WhatIsGoingOn {}
boolean iThinkThisIsAllowedButWeDontReallyCare = true;
}
}
}

View File

@ -1,28 +0,0 @@
# TODO: Deal with duplicates (bruh = 10; bruh = 10;) being marked as definitions
bruh = 10
class Bruh(object):
a: int
def __init__(self) -> None:
pass
def dab():
print("yay!")
def more():
print("a function in a function!!")
pass
more()
if 1 == 1:
notHere = False
while False:
notHereEither = False
for i in range(0, 0):
definitelyNotInHere = False
with 1:
what = "is this even allowed in Python anymore?"

View File

@ -1,33 +0,0 @@
class MyClass {
public_field: number
#private_field: number
private also_private_field: number
public_method() {}
#private_method() {}
private also_private_method() {}
}
interface MyInterface {
bruh: number,
sayBruh(): void,
}
enum MyEnum {
zig,
rust,
go,
}
var global1 = 0;
var global2;
function func() {
var c;
function inAnotherFunc() {
var b;
function inAnother() {
var a;
}
}
}

View File

@ -1,49 +0,0 @@
pub const Bruh = struct {
zig_is_cool: bool = true,
pub fn init() Bruh {
var aaa = false;
return .{};
}
};
const MyUnion = union {
const decl = 10;
a: u8,
b: u40,
pub fn init() void {};
};
const MyEnum = enum {
const decl = 10;
a,
b,
pub fn init() void {};
};
const MyUnionEnum = union(enum) {
const decl = 10;
a: u8,
b: u40,
pub fn init() void {};
};
const Ahh = opaque {
pub fn opaqueFn() void {}
}
fn bruh() void {
const ThisShouldntBeRegistered = struct {
fn bruh2() void {}
}
}
fn complex(a: struct {bruh: bool}) struct {dab: u8} {
return .{.dab = if (a.bruh) 10 else 20};
}

View File

@ -1,38 +0,0 @@
package multierror
import "sync"
// Group is a collection of goroutines which return errors that need to be
// coalesced.
type Group struct {
mutex sync.Mutex
err *Error
wg sync.WaitGroup
}
// Go calls the given function in a new goroutine.
//
// If the function returns an error it is added to the group multierror which
// is returned by Wait.
func (g *Group) Go(f func() error) {
g.wg.Add(1)
go func() {
defer g.wg.Done()
if err := f(); err != nil {
g.mutex.Lock()
g.err = Append(g.err, err)
g.mutex.Unlock()
}
}()
}
// Wait blocks until all function calls from the Go method have returned, then
// returns the multierror.
func (g *Group) Wait() *Error {
g.wg.Wait()
g.mutex.Lock()
defer g.mutex.Unlock()
return g.err
}

View File

@ -1,27 +0,0 @@
package memo
import "sync"
// MemoizedConstructorWithArg wraps a function returning taking a
// single argument value and returning a value and an error, memoizing
// its result. Multiple calls to Init will result in the underlying
// constructor being called once. The arguments to the call will be the
// first call to occur. All callers will receive the same return values.
type MemoizedConstructorWithArg[A, T any] struct {
ctor func(A) (T, error)
value T
err error
once sync.Once
}
// NewMemoizedConstructor memoizes the given constructor
func NewMemoizedConstructorWithArg[A, T any](ctor func(A) (T, error)) *MemoizedConstructorWithArg[A, T] {
return &MemoizedConstructorWithArg[A, T]{ctor: ctor}
}
// Init ensures that the given constructor has been called exactly
// once, then returns the constructor's result value and error.
func (m *MemoizedConstructorWithArg[A, T]) Init(arg A) (T, error) {
m.once.Do(func() { m.value, m.err = m.ctor(arg) })
return m.value, m.err
}

View File

@ -78,56 +78,4 @@ impl BundledParser {
_ => None,
}
}
pub fn get_language_name(&self) -> &str {
match self {
BundledParser::C => "c",
BundledParser::Cpp => "cpp",
BundledParser::C_Sharp => "c_sharp",
BundledParser::Go => "go",
BundledParser::Java => "java",
BundledParser::Javascript => "javascript",
BundledParser::Jsonnet => "jsonnet",
BundledParser::Kotlin => "kotlin",
BundledParser::Nickel => "nickel",
BundledParser::Perl => "perl",
BundledParser::Pod => "pod",
BundledParser::Python => "python",
BundledParser::Ruby => "ruby",
BundledParser::Rust => "rust",
BundledParser::Scala => "scala",
BundledParser::Sql => "sql",
BundledParser::Typescript => "typescript",
BundledParser::Tsx => "tsx",
BundledParser::Xlsg => "xlsg",
BundledParser::Zig => "zig",
}
}
// TODO(SuperAuguste): language detection library
pub fn get_parser_from_extension(name: &str) -> Option<Self> {
match name {
"c" => Some(BundledParser::C),
"cpp" => Some(BundledParser::Cpp),
"cs" => Some(BundledParser::C_Sharp),
"go" => Some(BundledParser::Go),
"java" => Some(BundledParser::Java),
"js" => Some(BundledParser::Javascript),
"jsonnet" => Some(BundledParser::Jsonnet),
"kt" => Some(BundledParser::Kotlin),
"ncl" => Some(BundledParser::Nickel),
"pl" => Some(BundledParser::Perl),
"pod" => Some(BundledParser::Pod),
"py" => Some(BundledParser::Python),
"rb" => Some(BundledParser::Ruby),
"rs" => Some(BundledParser::Rust),
"scala" => Some(BundledParser::Scala),
"sql" => Some(BundledParser::Sql),
"ts" => Some(BundledParser::Typescript),
"tsx" => Some(BundledParser::Tsx),
"xlsg" => Some(BundledParser::Xlsg),
"zig" => Some(BundledParser::Zig),
_ => None,
}
}
}

View File

@ -1,5 +1,3 @@
use tree_sitter::Node;
#[derive(Debug, PartialEq, Eq, Default)]
pub struct PackedRange {
pub start_line: i32,
@ -31,14 +29,6 @@ impl PackedRange {
}
}
pub fn to_vec(&self) -> Vec<i32> {
if self.start_line == self.end_line {
vec![self.start_line, self.start_col, self.end_col]
} else {
vec![self.start_line, self.start_col, self.end_line, self.end_col]
}
}
/// Checks if the range is equal to the given vector.
/// If the other vector is not a valid PackedRange then it returns false
pub fn eq_vec(&self, v: &[i32]) -> bool {
@ -58,13 +48,6 @@ impl PackedRange {
_ => false,
}
}
pub fn contains(&self, other: &PackedRange) -> bool {
other.start_line >= self.start_line
&& other.end_line <= self.end_line
&& (other.start_line != self.start_line || other.start_col >= self.start_col)
&& (other.end_line != self.end_line || other.end_col <= self.end_col)
}
}
impl PartialOrd for PackedRange {
@ -86,64 +69,3 @@ impl Ord for PackedRange {
))
}
}
impl<'a> From<Node<'a>> for PackedRange {
fn from(node: Node<'a>) -> Self {
let start = node.start_position();
let end = node.end_position();
Self {
start_line: start.row as i32,
start_col: start.column as i32,
end_line: end.row as i32,
end_col: end.column as i32,
}
}
}
#[cfg(test)]
mod tests {
use super::PackedRange;
#[test]
fn test_packed_range_contains() {
let outer = PackedRange {
start_line: 1,
start_col: 1,
end_line: 4,
end_col: 4,
};
let inner = PackedRange {
start_line: 2,
start_col: 2,
end_line: 3,
end_col: 3,
};
let overlapping = PackedRange {
start_line: 3,
start_col: 3,
end_line: 5,
end_col: 5,
};
let outside = PackedRange {
start_line: 5,
start_col: 5,
end_line: 6,
end_col: 6,
};
let same = PackedRange {
start_line: 1,
start_col: 1,
end_line: 4,
end_col: 4,
};
assert!(outer.contains(&inner));
assert!(!outer.contains(&overlapping));
assert!(!outer.contains(&outside));
assert!(outer.contains(&same));
}
}

View File

@ -1,2 +0,0 @@
review:
warn_undiscovered: false

View File

@ -1,7 +0,0 @@
download-bench:
mkdir -p bench_data/
test -f bench_data/event.rs || curl -o bench_data/event.rs https://raw.githubusercontent.com/alacritty/alacritty/ead65221ebe06ff5689e65b866d735d4365d0e9e/alacritty/src/event.rs
test -f bench_data/big.cpp || curl -o bench_data/big.cpp https://raw.githubusercontent.com/llvm/llvm-project/ff2e6199b23525b06947785368cc3e2e93eab381/llvm/lib/Target/X86/X86ISelLowering.cpp
bench: download-bench
cargo bench

View File

@ -1,12 +0,0 @@
use std::io::{BufReader, BufWriter};
use scip_syntax::ctags::ctags_runner;
fn main() {
let mut stdin = BufReader::new(std::io::stdin());
let mut stdout = BufWriter::new(std::io::stdout());
if let Err(err) = ctags_runner(&mut stdin, &mut stdout) {
eprintln!("Error while executing: {}", err);
}
}

View File

@ -3,14 +3,7 @@
#[macro_use]
extern crate rocket;
use std::path;
use ::scip::types::Document;
use protobuf::Message;
use rocket::serde::json::{json, Json, Value as JsonValue};
use scip_syntax::get_globals;
use scip_treesitter_languages::parsers::BundledParser;
use serde::Deserialize;
use sg_syntax::{ScipHighlightQuery, SourcegraphQuery};
#[post("/", format = "application/json", data = "<q>")]
@ -45,60 +38,6 @@ fn scip(q: Json<ScipHighlightQuery>) -> JsonValue {
}
}
#[derive(Deserialize, Default, Debug)]
pub struct SymbolQuery {
filename: String,
content: String,
}
pub fn jsonify_err(e: impl ToString) -> JsonValue {
json!({"error": e.to_string()})
}
#[post("/symbols", format = "application/json", data = "<q>")]
fn symbols(q: Json<SymbolQuery>) -> JsonValue {
let path = path::Path::new(&q.filename);
let extension = match match path.extension() {
Some(vals) => vals,
None => {
return json!({"error": "Extensionless file"});
}
}
.to_str()
{
Some(vals) => vals,
None => {
return json!({"error": "Invalid codepoint"});
}
};
let parser = match BundledParser::get_parser_from_extension(extension) {
Some(parser) => parser,
None => return json!({"error": "Could not infer parser from extension"}),
};
let (mut scope, hint) = match match get_globals(&parser, q.content.as_bytes()) {
Some(globals) => globals,
None => return json!({"error": "Failed to get globals"}),
} {
Ok(vals) => vals,
Err(err) => {
return jsonify_err(err);
}
};
let mut document = Document::default();
document.occurrences = scope.into_occurrences(hint, vec![]);
let encoded = match document.write_to_bytes() {
Ok(vals) => vals,
Err(err) => {
return jsonify_err(err);
}
};
json!({"scip": base64::encode(encoded), "plaintext": false})
}
#[get("/health")]
fn health() -> &'static str {
"OK"
@ -120,8 +59,8 @@ fn rocket() -> _ {
Ok(v) if v == "true" => {
println!("Sanity check passed, exiting without error");
std::process::exit(0)
}
_ => {}
},
_ => {},
};
// load configurations on-startup instead of on-first-request.
@ -137,6 +76,6 @@ fn rocket() -> _ {
};
rocket::build()
.mount("/", routes![syntect, lsif, scip, symbols, health])
.mount("/", routes![syntect, lsif, scip, health])
.register("/", catchers![not_found])
}

View File

@ -11,8 +11,6 @@ cleanup() {
}
trap cleanup EXIT
echo "--- :bazel: bazel build for targets //enterprise/cmd/symbols"
bazelrc=(
--bazelrc=.bazelrc
)
@ -23,6 +21,7 @@ if [[ ${CI:-""} == "true" ]]; then
)
fi
echo "--- bazel build"
bazel "${bazelrc[@]}" \
build \
//enterprise/cmd/symbols \
@ -31,38 +30,18 @@ bazel "${bazelrc[@]}" \
--config incompat-zig-linux-amd64
out=$(
bazel "${bazelrc[@]}" \
cquery //enterprise/cmd/symbols \
bazel \
"${bazelrc[@]}" \
cquery \
//enterprise/cmd/symbols \
--stamp \
--workspace_status_command=./dev/bazel_stamp_vars.sh \
--config incompat-zig-linux-amd64 \
--output=files
)
cp -v "$out" "$OUTPUT"
# we can't build scip-ctags with symbols since the platform args conflict
# NOTE: cmd/symbols/cargo-config.sh sets some specific config when running on arm64
# since this bazel run typically runs on CI that config change isn't made
echo "--- :bazel: bazel build for target //docker-images/syntax-highlighter:scip-ctags"
bazel "${bazelrc[@]}" \
build //docker-images/syntax-highlighter:scip-ctags \
--stamp \
--workspace_status_command=./dev/bazel_stamp_vars.sh
out=$(
bazel "${bazelrc[@]}" \
cquery //docker-images/syntax-highlighter:scip-ctags \
--stamp \
--workspace_status_command=./dev/bazel_stamp_vars.sh \
--output=files
)
cp -v "$out" "$OUTPUT"
cp "$out" "$OUTPUT"
cp cmd/symbols/ctags-install-alpine.sh "$OUTPUT"
echo ":docker: context directory contains the following:"
ls -lah "$OUTPUT"
echo "--- :docker: docker build for symbols"
docker build -f cmd/symbols/Dockerfile.bazel -t "$IMAGE" "$OUTPUT" \
--progress=plain \
--build-arg COMMIT_SHA \

View File

@ -17,7 +17,6 @@ go_library(
"//enterprise/internal/rockskip",
"//internal/conf",
"//internal/conf/conftypes",
"//internal/ctags_config",
"//internal/database",
"//internal/database/connections/live",
"//internal/debugserver",

View File

@ -17,7 +17,6 @@ import (
"github.com/sourcegraph/sourcegraph/enterprise/internal/rockskip"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/conf/conftypes"
"github.com/sourcegraph/sourcegraph/internal/ctags_config"
"github.com/sourcegraph/sourcegraph/internal/database"
connections "github.com/sourcegraph/sourcegraph/internal/database/connections/live"
"github.com/sourcegraph/sourcegraph/internal/env"
@ -128,14 +127,14 @@ func setupRockskip(observationCtx *observation.Context, config rockskipConfig, g
codeintelDB := mustInitializeCodeIntelDB(observationCtx)
createParser := func() (ctags.Parser, error) {
return symbolsParser.SpawnCtags(log.Scoped("parser", "ctags parser"), config.Ctags, ctags_config.UniversalCtags)
return symbolsParser.SpawnCtags(log.Scoped("parser", "ctags parser"), config.Ctags)
}
server, err := rockskip.NewService(codeintelDB, gitserverClient, repositoryFetcher, createParser, config.MaxConcurrentlyIndexing, config.MaxRepos, config.LogQueries, config.IndexRequestsQueueSize, config.SymbolsCacheSize, config.PathSymbolsCacheSize, config.SearchLastIndexedCommit)
if err != nil {
return nil, nil, config.Ctags.UniversalCommand, err
return nil, nil, config.Ctags.Command, err
}
return server.Search, server.HandleStatus, config.Ctags.UniversalCommand, nil
return server.Search, server.HandleStatus, config.Ctags.Command, nil
}
func mustInitializeCodeIntelDB(observationCtx *observation.Context) *sql.DB {

4
go.mod
View File

@ -113,7 +113,7 @@ require (
github.com/getsentry/sentry-go v0.21.0
github.com/ghodss/yaml v1.0.0
github.com/gitchander/permutation v0.0.0-20210517125447-a5d73722e1b1
github.com/go-enry/go-enry/v2 v2.8.4
github.com/go-enry/go-enry/v2 v2.8.3
github.com/go-git/go-git/v5 v5.5.2
github.com/go-openapi/strfmt v0.21.3
github.com/gobwas/glob v0.2.3
@ -533,7 +533,7 @@ require (
go.opentelemetry.io/collector/pdata v1.0.0-rc5 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.13.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a
golang.org/x/mod v0.8.0
golang.org/x/term v0.8.0 // indirect
golang.org/x/text v0.9.0

8
go.sum
View File

@ -793,8 +793,8 @@ github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-enry/go-enry/v2 v2.8.4 h1:QrY3hx/RiqCJJRbdU0MOcjfTM1a586J0WSooqdlJIhs=
github.com/go-enry/go-enry/v2 v2.8.4/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
github.com/go-enry/go-enry/v2 v2.8.3 h1:BwvNrN58JqBJhyyVdZSl5QD3xoxEEGYUrRyPh31FGhw=
github.com/go-enry/go-enry/v2 v2.8.3/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ=
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
@ -2476,8 +2476,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a h1:4iLhBPcpqFmylhnkbY3W0ONLUYYkDAW9xMFLfxgsvCw=
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=

View File

@ -1,9 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "ctags_config",
srcs = ["ctags_config.go"],
importpath = "github.com/sourcegraph/sourcegraph/internal/ctags_config",
visibility = ["//:__subpackages__"],
deps = ["//lib/errors"],
)

View File

@ -1,42 +0,0 @@
package ctags_config
import "github.com/sourcegraph/sourcegraph/lib/errors"
type ParserType = uint8
const (
UnknownCtags ParserType = iota
NoCtags
UniversalCtags
ScipCtags
)
func ParserNameToParserType(name string) (ParserType, error) {
switch name {
case "off":
return NoCtags, nil
case "universal-ctags":
return UniversalCtags, nil
case "scip-ctags":
return ScipCtags, nil
default:
return UnknownCtags, errors.Errorf("unknown parser type: %s", name)
}
}
type ParserConfiguration struct {
Default ParserType
Engine map[string]ParserType
}
var SupportLanguages = map[string]struct{}{
"Zig": {},
}
var BaseParserConfig = ParserConfiguration{
Engine: map[string]ParserType{
// TODO: put our other languages here
// TODO: also list the languages we support
"Zig": ScipCtags,
},
}

View File

@ -1,12 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "languages",
srcs = ["languages.go"],
importpath = "github.com/sourcegraph/sourcegraph/lib/codeintel/languages",
visibility = ["//visibility:public"],
deps = [
"@com_github_go_enry_go_enry_v2//:go-enry",
"@org_golang_x_exp//slices",
],
)

View File

@ -1,53 +0,0 @@
package languages
import (
"github.com/go-enry/go-enry/v2"
"golang.org/x/exp/slices"
)
// TODO: We probably want to move the config for language detection into here from the syntax highlighting part
// I didn't add that yet.
// GetLanguage returns the language for the given path and contents.
func GetLanguage(path, contents string) (lang string, found bool) {
// Force the use of the shebang.
if shebangLang, ok := overrideViaShebang(path, contents); ok {
return shebangLang, true
}
// Lastly, fall back to whatever enry decides is a useful algorithm for calculating.
lang = enry.GetLanguage(path, []byte(contents))
if lang != "" {
return lang, true
}
return lang, false
}
// overrideViaShebang handles explicitly using the shebang whenever possible.
//
// It also covers some edge cases when enry eagerly returns more languages
// than necessary, which ends up overriding the shebang completely (which,
// IMO is the highest priority match we can have).
//
// For example, enry will return "Perl" and "Pod" for a shebang of `#!/usr/bin/env perl`.
// This is actually unhelpful, because then enry will *not* select "Perl" as the
// language (which is our desired behavior).
func overrideViaShebang(path, content string) (lang string, ok bool) {
shebangs := enry.GetLanguagesByShebang(path, []byte(content), []string{})
if len(shebangs) == 0 {
return "", false
}
if len(shebangs) == 1 {
return shebangs[0], true
}
// There are some shebangs that enry returns that are not really
// useful for our syntax highlighters to distinguish between.
if slices.Equal(shebangs, []string{"Perl", "Pod"}) {
return "Perl", true
}
return "", false
}

View File

@ -9,7 +9,6 @@ require (
github.com/derision-test/go-mockgen v1.3.7
github.com/fatih/color v1.13.0
github.com/ghodss/yaml v1.0.0
github.com/go-enry/go-enry/v2 v2.8.4
github.com/gobwas/glob v0.2.3
github.com/google/go-cmp v0.5.9
github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db
@ -28,7 +27,7 @@ require (
github.com/stretchr/testify v1.8.1
github.com/urfave/cli/v2 v2.23.7
github.com/xeipuuv/gojsonschema v1.2.0
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
go.uber.org/atomic v1.10.0
golang.org/x/sync v0.1.0
golang.org/x/sys v0.3.0
golang.org/x/term v0.3.0
@ -56,7 +55,6 @@ require (
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/envoyproxy/protoc-gen-validate v0.6.13 // indirect
github.com/getsentry/sentry-go v0.15.0 // indirect
github.com/go-enry/go-oniguruma v1.2.1 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gofrs/uuid v4.2.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
@ -104,7 +102,6 @@ require (
github.com/yuin/goldmark v1.5.2 // indirect
github.com/yuin/goldmark-emoji v1.0.1 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/goleak v1.2.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.24.0 // indirect

View File

@ -151,10 +151,6 @@ github.com/getsentry/sentry-go v0.15.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2Ht
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-enry/go-enry/v2 v2.8.4 h1:QrY3hx/RiqCJJRbdU0MOcjfTM1a586J0WSooqdlJIhs=
github.com/go-enry/go-enry/v2 v2.8.4/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@ -576,8 +572,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=

View File

@ -61,7 +61,7 @@ require (
go.uber.org/goleak v1.2.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a // indirect
golang.org/x/oauth2 v0.2.0 // indirect
golang.org/x/sys v0.3.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect

View File

@ -448,8 +448,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o=
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a h1:4iLhBPcpqFmylhnkbY3W0ONLUYYkDAW9xMFLfxgsvCw=
golang.org/x/exp v0.0.0-20221208152030-732eee02a75a/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -645,7 +645,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.4.0 h1:7mTAgkunk3fr4GAloyyCasadO6h9zSsQZbwvcaIciV4=
golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -2772,18 +2772,10 @@ type SubRepoPermissions struct {
UserCacheTTLSeconds int `json:"userCacheTTLSeconds,omitempty"`
}
// SymbolConfiguration description: Configure symbol generation
type SymbolConfiguration struct {
// Engine description: Manually specify overrides for symbol generation engine per language
Engine map[string]string `json:"engine"`
}
// SyntaxHighlighting description: Syntax highlighting configuration
type SyntaxHighlighting struct {
Engine SyntaxHighlightingEngine `json:"engine"`
Languages SyntaxHighlightingLanguage `json:"languages"`
// Symbols description: Configure symbol generation
Symbols SymbolConfiguration `json:"symbols"`
}
type SyntaxHighlightingEngine struct {
// Default description: The default syntax highlighting engine to use

View File

@ -848,7 +848,7 @@
"title": "SyntaxHighlighting",
"description": "Syntax highlighting configuration",
"type": "object",
"required": ["engine", "languages", "symbols"],
"required": ["engine", "languages"],
"properties": {
"engine": {
"title": "SyntaxHighlightingEngine",
@ -903,22 +903,6 @@
}
}
}
},
"symbols": {
"title": "SymbolConfiguration",
"description": "Configure symbol generation",
"type": "object",
"required": ["engine"],
"properties": {
"engine": {
"description": "Manually specify overrides for symbol generation engine per language",
"type": "object",
"additionalProperties": {
"type": "string",
"enum": ["universal-ctags", "scip-ctags", "off"]
}
}
}
}
},
"examples": [

View File

@ -340,7 +340,6 @@ commands:
checkBinary: .bin/oss-symbols
env:
CTAGS_COMMAND: dev/universal-ctags-dev
SCIP_CTAGS_COMMAND: dev/scip-ctags-dev
CTAGS_PROCESSES: 2
watch:
- lib
@ -359,7 +358,6 @@ commands:
checkBinary: .bin/symbols
env:
CTAGS_COMMAND: dev/universal-ctags-dev
SCIP_CTAGS_COMMAND: dev/scip-ctags-dev
CTAGS_PROCESSES: 2
USE_ROCKSKIP: "false"
watch:
@ -546,7 +544,6 @@ commands:
checkBinary: .bin/zoekt-sourcegraph-indexserver
env: &zoektenv
CTAGS_COMMAND: dev/universal-ctags-dev
SCIP_CTAGS_COMMAND: dev/scip-ctags-dev
GRPC_ENABLED: true
zoekt-index-0:
@ -959,7 +956,6 @@ bazelCommands:
target: //cmd/symbols
env:
CTAGS_COMMAND: dev/universal-ctags-dev
SCIP_CTAGS_COMMAND: dev/scip-ctags-dev
CTAGS_PROCESSES: 2
oss-gitserver-0:
target: //cmd/gitserver
@ -1027,7 +1023,6 @@ bazelCommands:
checkBinary: .bin/symbols
env:
CTAGS_COMMAND: dev/universal-ctags-dev
SCIP_CTAGS_COMMAND: dev/scip-ctags-dev
CTAGS_PROCESSES: 2
USE_ROCKSKIP: "false"
gitserver-template: &gitserver_bazel_template