├── .bazelignore ├── .bazelversion ├── .dockerignore ├── .github ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yml ├── labeler.yml ├── release-drafter.yml └── workflows │ ├── ci.yml │ ├── labeler.yml │ ├── mdoc.yml │ ├── pr-auditor.yml │ ├── release-docker.yml │ ├── release-maven.yml │ └── sourcegraph.yml ├── .gitignore ├── .jvmopts ├── .scalafix.conf ├── .scalafmt.conf ├── .tool-versions ├── BUILD ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── README.md ├── WORKSPACE ├── bin ├── coursier ├── docker-setup.sh ├── packagehub.sh └── scip-java-docker-script.sh ├── build.sbt ├── docs ├── assets │ └── semanticdb-javac-pipeline.svg ├── benchmarks.md ├── contributing.md ├── design.md ├── getting-started.md └── manual-configuration.md ├── examples ├── bazel-example │ ├── .bazelversion │ ├── .gitignore │ ├── WORKSPACE │ ├── aspects │ │ └── BUILD │ └── src │ │ └── main │ │ └── java │ │ ├── example │ │ ├── BUILD │ │ └── Example.java │ │ ├── source-generator-example │ │ ├── Animal.java │ │ └── BUILD │ │ └── srcjar_example │ │ ├── BUILD │ │ ├── Baz.java │ │ └── Foo.java └── maven-example │ ├── pom.xml │ └── src │ ├── main │ └── java │ │ └── App.java │ └── test │ └── java │ └── AppTest.java ├── maven-plugin └── src │ └── main │ ├── java │ └── com │ │ └── sourcegraph │ │ └── maven │ │ └── DependencyWriterMojo.java │ └── resources │ └── META-INF │ └── maven │ └── plugin.template.xml ├── project ├── JavaToolchainPlugin.scala ├── build.properties └── plugins.sbt ├── renovate.json ├── sbt ├── scip-java-proto └── src │ └── main │ └── protobuf │ ├── BUILD │ └── scip.proto ├── scip-java └── src │ └── main │ ├── resources │ └── scip-java │ │ └── scip_java.bzl │ └── scala │ └── com │ └── sourcegraph │ ├── io │ ├── AbsolutePath.scala │ ├── AutoDeletedFile.scala │ └── DeleteVisitor.scala │ ├── scip_java │ ├── Dependencies.scala │ ├── Embedded.scala │ ├── ScipJava.scala │ ├── ScipPrinters.scala │ ├── ScipSymbol.scala │ ├── buildtools │ │ ├── BazelBuildTool.scala │ │ ├── BuildTool.scala │ │ ├── ClasspathEntry.scala │ │ ├── GradleBuildTool.scala │ │ ├── GradleJavaCompiler.scala │ │ ├── GradleJavaToolchains.scala │ │ ├── MavenBuildTool.scala │ │ ├── MillBuildTool.scala │ │ ├── SbtBuildTool.scala │ │ ├── ScalaCompilerClassLoader.scala │ │ ├── ScalaVersion.scala │ │ ├── ScipBuildTool.scala │ │ ├── SystemJavaVersion.scala │ │ └── TemporaryFiles.scala │ └── commands │ │ ├── CommentSyntax.scala │ │ ├── IndexCommand.scala │ │ ├── IndexDependencyCommand.scala │ │ ├── IndexSemanticdbCommand.scala │ │ ├── SnapshotCommand.scala │ │ └── SnapshotLsifCommand.scala │ └── scip_semanticdb │ ├── ConsolescipSemanticdbReporter.scala │ └── ScipSemanticdbProgressRenderer.scala ├── scip-semanticdb ├── BUILD └── src │ └── main │ ├── java │ └── com │ │ └── sourcegraph │ │ └── scip_semanticdb │ │ ├── BazelBuildTool.java │ │ ├── BazelOptions.java │ │ ├── InputStreamBytes.java │ │ ├── JavaVersion.java │ │ ├── JdkPackage.java │ │ ├── MarkupContent.java │ │ ├── MavenPackage.java │ │ ├── MessageOnlyException.java │ │ ├── OperatingSystem.java │ │ ├── Package.java │ │ ├── PackageTable.java │ │ ├── RangeComparator.java │ │ ├── ResultIds.java │ │ ├── ResultSets.java │ │ ├── ScipByteOutputStream.java │ │ ├── ScipOutputFormat.java │ │ ├── ScipOutputStream.java │ │ ├── ScipProcessingException.java │ │ ├── ScipSemanticdb.java │ │ ├── ScipSemanticdbOptions.java │ │ ├── ScipSemanticdbReporter.java │ │ ├── ScipTextDocument.java │ │ ├── ScipWriter.java │ │ ├── SemanticdbTreeVisitor.java │ │ ├── SemanticdbWalker.java │ │ ├── SignatureFormatter.java │ │ ├── SignatureFormatterException.java │ │ ├── SymbolDescriptor.java │ │ ├── SymbolOccurrences.java │ │ ├── SymbolRelationship.java │ │ └── Symtab.java │ └── protobuf │ ├── bazelbuild.proto │ └── lsif.proto ├── semanticdb-agent └── src │ └── main │ └── java │ └── com │ └── sourcegraph │ └── semanticdb_javac │ └── SemanticdbAgent.java ├── semanticdb-gradle-plugin └── src │ └── main │ └── scala │ └── SemanticdbGradlePlugin.scala ├── semanticdb-java ├── BUILD └── src │ └── main │ ├── java │ └── com │ │ └── sourcegraph │ │ └── semanticdb_javac │ │ ├── SemanticdbBuilders.java │ │ └── SemanticdbSymbols.java │ └── protobuf │ ├── BUILD │ └── semanticdb.proto ├── semanticdb-javac ├── BUILD ├── defs.bzl └── src │ └── main │ ├── java │ └── com │ │ └── sourcegraph │ │ └── semanticdb_javac │ │ ├── CompilationUnitException.java │ │ ├── CompilerRange.java │ │ ├── Debugging.java │ │ ├── GlobalSymbolsCache.java │ │ ├── InjectSemanticdbOptions.java │ │ ├── LocalSymbolsCache.java │ │ ├── MD5.java │ │ ├── NoRelativePathMode.java │ │ ├── PrintJavaVersion.java │ │ ├── RangeFinder.java │ │ ├── Result.java │ │ ├── SemanticdbJavacOptions.java │ │ ├── SemanticdbOptionBuilder.java │ │ ├── SemanticdbPlugin.java │ │ ├── SemanticdbReporter.java │ │ ├── SemanticdbSignatures.java │ │ ├── SemanticdbTaskListener.java │ │ ├── SemanticdbTrees.java │ │ ├── SemanticdbTypeVisitor.java │ │ ├── SemanticdbVisitor.java │ │ ├── TargetPaths.java │ │ └── UriScheme.java │ └── resources │ └── META-INF │ └── services │ └── com.sun.source.util.Plugin ├── tests ├── benchmarks │ └── src │ │ └── main │ │ └── scala │ │ └── benchmarks │ │ ├── CompileBench.scala │ │ └── ScipSemanticdbBench.scala ├── buildTools │ └── src │ │ ├── main │ │ └── scala │ │ │ └── tests │ │ │ ├── GradleDefaultJvmLanguageCompileSpec.scala │ │ │ └── GradleJavaCompilerArgumentsBuilder.scala │ │ └── test │ │ ├── resources │ │ ├── example-maven-pom.xml │ │ └── mill │ │ └── scala │ │ └── tests │ │ ├── AutoBuildToolSuite.scala │ │ ├── BaseBuildToolSuite.scala │ │ ├── GradleBuildToolSuite.scala │ │ ├── GradleBuildToolSuiteBase.scala │ │ ├── GradleDefaultJvmLanguageCompileSpecSuite.scala │ │ ├── GradleJavaCompilerArgumentsBuilderSuite.scala │ │ ├── MavenBuildToolSuite.scala │ │ ├── MillBuildToolSuite.scala │ │ ├── MissingBuildToolSuite.scala │ │ ├── SbtBuildToolSuite.scala │ │ ├── ScipBuildToolSuite.scala │ │ ├── SkipWindows.scala │ │ ├── Tool.scala │ │ └── TracingServer.scala ├── gradle-example │ ├── .gitignore │ ├── build.gradle │ └── src │ │ ├── main │ │ └── java │ │ │ └── example │ │ │ └── Example.java │ │ └── test │ │ └── java │ │ └── example │ │ └── ExampleTest.java ├── minimized-scala │ └── src │ │ └── main │ │ └── scala │ │ └── minimized │ │ ├── Issue396.scala │ │ ├── Issue397.scala │ │ ├── Issue403.scala │ │ ├── Issue412.scala │ │ ├── Issue413.scala │ │ ├── Issue414.scala │ │ ├── Issue414Reference.scala │ │ ├── MinimizedScalaMain.scala │ │ ├── MinimizedScalaSignatures.scala │ │ ├── MinimizedScalaSynthetic.scala │ │ └── ReflectiveCall.scala ├── minimized │ ├── BUILD │ └── src │ │ └── main │ │ └── java │ │ └── minimized │ │ ├── AbstractClasses.java │ │ ├── AnnotationParameters.java │ │ ├── Annotations.java │ │ ├── AnnotationsOnParameterizedTypes.java │ │ ├── AnonymousClasses.java │ │ ├── Arrays.java │ │ ├── ClassOf.java │ │ ├── Docstrings.java │ │ ├── Enums.java │ │ ├── Fields.java │ │ ├── ForComprehensions.java │ │ ├── InnerClasses.java │ │ ├── Interfaces.java │ │ ├── LombokBuilder.java │ │ ├── Methods.java │ │ ├── MinimizedJavaMain.java │ │ ├── ParameterizedTypes.java │ │ ├── Primitives.java │ │ ├── RawTypes.java │ │ ├── SubClasses.java │ │ ├── TabIndented.java │ │ ├── TypeAnnotations.java │ │ └── TypeVariables.java ├── snapshots │ └── src │ │ ├── main │ │ ├── generated │ │ │ ├── BaseByteRenderer.scala │ │ │ ├── BaseCharRenderer.scala │ │ │ ├── ByteParser.scala │ │ │ ├── CharParser.scala │ │ │ ├── com │ │ │ │ └── airbnb │ │ │ │ │ └── epoxy │ │ │ │ │ ├── ActivityRecyclerPool.kt │ │ │ │ │ ├── AsyncEpoxyController.java │ │ │ │ │ ├── AsyncEpoxyDiffer.java │ │ │ │ │ ├── BaseEpoxyAdapter.java │ │ │ │ │ ├── BaseEpoxyTouchCallback.java │ │ │ │ │ ├── BoundViewHolders.java │ │ │ │ │ ├── Carousel.java │ │ │ │ │ ├── ControllerHelper.java │ │ │ │ │ ├── ControllerHelperLookup.java │ │ │ │ │ ├── ControllerModelList.java │ │ │ │ │ ├── DebugTimer.java │ │ │ │ │ ├── DiffHelper.java │ │ │ │ │ ├── DiffPayload.java │ │ │ │ │ ├── DiffResult.java │ │ │ │ │ ├── EpoxyAdapter.java │ │ │ │ │ ├── EpoxyAsyncUtil.java │ │ │ │ │ ├── EpoxyController.java │ │ │ │ │ ├── EpoxyControllerAdapter.java │ │ │ │ │ ├── EpoxyDiffLogger.java │ │ │ │ │ ├── EpoxyDragCallback.java │ │ │ │ │ ├── EpoxyHolder.java │ │ │ │ │ ├── EpoxyItemSpacingDecorator.java │ │ │ │ │ ├── EpoxyModel.java │ │ │ │ │ ├── EpoxyModelGroup.java │ │ │ │ │ ├── EpoxyModelTouchCallback.java │ │ │ │ │ ├── EpoxyModelWithHolder.java │ │ │ │ │ ├── EpoxyModelWithView.java │ │ │ │ │ ├── EpoxyRecyclerView.kt │ │ │ │ │ ├── EpoxySwipeCallback.java │ │ │ │ │ ├── EpoxyTouchHelper.java │ │ │ │ │ ├── EpoxyTouchHelperCallback.java │ │ │ │ │ ├── EpoxyViewHolder.java │ │ │ │ │ ├── EpoxyVisibilityItem.kt │ │ │ │ │ ├── EpoxyVisibilityTracker.kt │ │ │ │ │ ├── GeneratedModel.java │ │ │ │ │ ├── GroupModel.kt │ │ │ │ │ ├── HandlerExecutor.java │ │ │ │ │ ├── HiddenEpoxyModel.java │ │ │ │ │ ├── IdUtils.java │ │ │ │ │ ├── IllegalEpoxyUsage.java │ │ │ │ │ ├── ImmutableModelException.java │ │ │ │ │ ├── InternalExposer.kt │ │ │ │ │ ├── ListenersUtils.java │ │ │ │ │ ├── MainThreadExecutor.java │ │ │ │ │ ├── ModelCollector.kt │ │ │ │ │ ├── ModelGroupHolder.kt │ │ │ │ │ ├── ModelList.java │ │ │ │ │ ├── ModelState.java │ │ │ │ │ ├── NoOpControllerHelper.java │ │ │ │ │ ├── NoOpTimer.java │ │ │ │ │ ├── NotifyBlocker.java │ │ │ │ │ ├── OnModelBoundListener.java │ │ │ │ │ ├── OnModelBuildFinishedListener.java │ │ │ │ │ ├── OnModelCheckedChangeListener.java │ │ │ │ │ ├── OnModelClickListener.java │ │ │ │ │ ├── OnModelLongClickListener.java │ │ │ │ │ ├── OnModelUnboundListener.java │ │ │ │ │ ├── OnModelVisibilityChangedListener.java │ │ │ │ │ ├── OnModelVisibilityStateChangedListener.java │ │ │ │ │ ├── QuantityStringResAttribute.java │ │ │ │ │ ├── SimpleEpoxyAdapter.java │ │ │ │ │ ├── SimpleEpoxyController.java │ │ │ │ │ ├── SimpleEpoxyModel.java │ │ │ │ │ ├── StringAttributeData.java │ │ │ │ │ ├── StyleBuilderCallback.java │ │ │ │ │ ├── Timer.java │ │ │ │ │ ├── Typed2EpoxyController.java │ │ │ │ │ ├── Typed3EpoxyController.java │ │ │ │ │ ├── Typed4EpoxyController.java │ │ │ │ │ ├── TypedEpoxyController.java │ │ │ │ │ ├── UnboundedViewPool.kt │ │ │ │ │ ├── UpdateOp.java │ │ │ │ │ ├── UpdateOpHelper.java │ │ │ │ │ ├── ViewHolderState.java │ │ │ │ │ ├── ViewTypeManager.java │ │ │ │ │ ├── VisibilityState.java │ │ │ │ │ ├── WrappedEpoxyModelCheckedChangeListener.java │ │ │ │ │ ├── WrappedEpoxyModelClickListener.kt │ │ │ │ │ ├── preload │ │ │ │ │ ├── EpoxyModelPreloader.kt │ │ │ │ │ ├── EpoxyPreloader.kt │ │ │ │ │ ├── PreloadTargetProvider.kt │ │ │ │ │ ├── Preloadable.kt │ │ │ │ │ ├── PreloadableViewDataProvider.kt │ │ │ │ │ └── PreloaderExtensions.kt │ │ │ │ │ ├── stickyheader │ │ │ │ │ ├── StickyHeaderCallbacks.kt │ │ │ │ │ └── StickyHeaderLinearLayoutManager.kt │ │ │ │ │ └── utils │ │ │ │ │ └── utils.kt │ │ │ ├── tests │ │ │ │ ├── minimized-scala │ │ │ │ │ └── src │ │ │ │ │ │ └── main │ │ │ │ │ │ └── scala │ │ │ │ │ │ └── minimized │ │ │ │ │ │ ├── Issue396.scala │ │ │ │ │ │ ├── Issue397.scala │ │ │ │ │ │ ├── Issue403.scala │ │ │ │ │ │ ├── Issue412.scala │ │ │ │ │ │ ├── Issue413.scala │ │ │ │ │ │ ├── Issue414.scala │ │ │ │ │ │ ├── Issue414Reference.scala │ │ │ │ │ │ ├── MinimizedScalaMain.scala │ │ │ │ │ │ ├── MinimizedScalaSignatures.scala │ │ │ │ │ │ ├── MinimizedScalaSynthetic.scala │ │ │ │ │ │ └── ReflectiveCall.scala │ │ │ │ └── minimized │ │ │ │ │ └── src │ │ │ │ │ └── main │ │ │ │ │ └── java │ │ │ │ │ └── minimized │ │ │ │ │ ├── AbstractClasses.java │ │ │ │ │ ├── AnnotationParameters.java │ │ │ │ │ ├── Annotations.java │ │ │ │ │ ├── AnnotationsOnParameterizedTypes.java │ │ │ │ │ ├── AnonymousClasses.java │ │ │ │ │ ├── Arrays.java │ │ │ │ │ ├── ClassOf.java │ │ │ │ │ ├── Docstrings.java │ │ │ │ │ ├── Enums.java │ │ │ │ │ ├── Fields.java │ │ │ │ │ ├── ForComprehensions.java │ │ │ │ │ ├── InnerClasses.java │ │ │ │ │ ├── Interfaces.java │ │ │ │ │ ├── LombokBuilder.java │ │ │ │ │ ├── Methods.java │ │ │ │ │ ├── MinimizedJavaMain.java │ │ │ │ │ ├── ParameterizedTypes.java │ │ │ │ │ ├── Primitives.java │ │ │ │ │ ├── RawTypes.java │ │ │ │ │ ├── SubClasses.java │ │ │ │ │ ├── TabIndented.java │ │ │ │ │ ├── TypeAnnotations.java │ │ │ │ │ └── TypeVariables.java │ │ │ └── ujson │ │ │ │ ├── AstTransformer.scala │ │ │ │ ├── ByteArrayParser.scala │ │ │ │ ├── ByteBufferParser.scala │ │ │ │ ├── CharSequenceParser.scala │ │ │ │ ├── Exceptions.scala │ │ │ │ ├── IndexedValue.scala │ │ │ │ ├── InputStreamParser.scala │ │ │ │ ├── JsVisitor.scala │ │ │ │ ├── Readable.scala │ │ │ │ ├── Renderer.scala │ │ │ │ ├── StringParser.scala │ │ │ │ ├── Transformer.scala │ │ │ │ ├── Value.scala │ │ │ │ └── package.scala │ │ └── scala │ │ │ └── tests │ │ │ ├── AggregateSnapshotGenerator.scala │ │ │ ├── AssertSnapshotHandlers.scala │ │ │ ├── LibrarySnapshotGenerator.scala │ │ │ ├── MinimizedSnapshotScipGenerator.scala │ │ │ ├── SaveSnapshotHandler.scala │ │ │ ├── SaveSnapshots.scala │ │ │ ├── SemanticdbFile.scala │ │ │ ├── SemanticdbJavacSnapshotGenerator.scala │ │ │ ├── SnapshotContext.scala │ │ │ ├── SnapshotGenerator.scala │ │ │ └── SnapshotHandler.scala │ │ └── test │ │ └── scala │ │ └── tests │ │ └── SnapshotSuite.scala └── unit │ └── src │ ├── main │ └── scala │ │ └── tests │ │ ├── CompileResult.scala │ │ ├── SimpleClassFile.java │ │ ├── SimpleFileManager.java │ │ ├── SimpleSourceFile.java │ │ ├── TempDirectories.scala │ │ ├── TestCompiler.scala │ │ └── Timer.scala │ └── test │ └── scala │ └── tests │ ├── GeneratedConstructorSuite.scala │ ├── JavaVersionSuite.scala │ ├── JavacClassesDirectorySuite.scala │ ├── OverridesSuite.scala │ ├── SbtSupportedVersionsSuite.scala │ ├── ScalaVersionSuite.scala │ ├── SnapshotCommandSuite.scala │ ├── SymbolDescriptorSuite.scala │ └── TargetedSuite.scala └── website ├── .gitignore ├── .tool-versions ├── README.md ├── core └── Footer.js ├── package.json ├── pages └── en │ └── index.js ├── project └── build.properties ├── sidebars.json ├── siteConfig.js └── static ├── css └── custom.css └── img ├── favicon.ico └── scip-java.png /.bazelignore: -------------------------------------------------------------------------------- 1 | examples/ 2 | 3 | -------------------------------------------------------------------------------- /.bazelversion: -------------------------------------------------------------------------------- 1 | 5.2.0 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | **/.git 4 | 5 | # sbt specific 6 | .cache 7 | .history 8 | .lib/ 9 | dist/* 10 | target/ 11 | lib_managed/ 12 | src_managed/ 13 | project/boot/ 14 | project/plugins/project/ 15 | .bloop 16 | 17 | _site/ 18 | 19 | # Scala-IDE specific 20 | .scala_dependencies 21 | .worksheet 22 | 23 | .idea 24 | 25 | # ENSIME specific 26 | .ensime_cache/ 27 | .ensime 28 | 29 | .metals/ 30 | metals.sbt 31 | metals/project/ 32 | 33 | .bsp 34 | 35 | .vscode/ 36 | 37 | local.* 38 | 39 | .DS_Store 40 | 41 | node_modules 42 | 43 | lib/core/metadata.js 44 | lib/core/MetadataBlog.js 45 | 46 | website/translated_docs 47 | website/build/ 48 | website/yarn.lock 49 | website/node_modules 50 | website/i18n/* 51 | 52 | project/metals.sbt 53 | out/ 54 | *.hnir 55 | test-report.json 56 | index.scip 57 | 58 | ./generated 59 | /sources 60 | bazel-bin 61 | bazel-scip-java 62 | bazel-out 63 | bazel-testlogs 64 | bazel-lsif-java 65 | 66 | VERSION 67 | 68 | semanticdb-gradle-plugin/gradle 69 | aspects/scip_java.bzl 70 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Test plan 2 | 3 | 10 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "monthly" 8 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | team/graph: 2 | - '/.*/' 3 | graph/scip-java: 4 | - '/.*/' 5 | -------------------------------------------------------------------------------- /.github/release-drafter.yml: -------------------------------------------------------------------------------- 1 | template: | 2 | ## Pull Requests 3 | 4 | $CHANGES 5 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | name: "Issue Labeler" 2 | on: 3 | issues: 4 | types: [opened, edited] 5 | 6 | permissions: 7 | issues: write 8 | contents: read 9 | 10 | jobs: 11 | triage: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: github/issue-labeler@v3.4 15 | with: 16 | configuration-path: .github/labeler.yml 17 | enable-versioned-regex: 0 18 | repo-token: ${{ github.token }} 19 | -------------------------------------------------------------------------------- /.github/workflows/mdoc.yml: -------------------------------------------------------------------------------- 1 | name: Website 2 | on: 3 | push: 4 | branches: [main] 5 | tags: ["*"] 6 | jobs: 7 | publish: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | with: 12 | fetch-depth: 0 13 | - uses: actions/setup-java@v3 14 | with: 15 | distribution: 'temurin' 16 | java-version: 11 17 | cache: 'sbt' 18 | - uses: sbt/setup-sbt@v1 19 | - run: sbt docs/docusaurusPublishGhpages 20 | env: 21 | GIT_DEPLOY_KEY: ${{ secrets.GIT_DEPLOY_KEY }} 22 | -------------------------------------------------------------------------------- /.github/workflows/pr-auditor.yml: -------------------------------------------------------------------------------- 1 | # See https://docs.sourcegraph.com/dev/background-information/ci#pr-auditor 2 | name: pr-auditor 3 | on: 4 | pull_request_target: 5 | types: [ closed, edited, opened, synchronize, ready_for_review ] 6 | workflow_dispatch: 7 | 8 | jobs: 9 | check-pr: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | repository: 'sourcegraph/devx-service' 15 | token: ${{ secrets.PR_AUDITOR_TOKEN }} 16 | - uses: actions/setup-go@v4 17 | with: { go-version: '1.22' } 18 | 19 | - run: 'go run ./cmd/pr-auditor' 20 | env: 21 | GITHUB_EVENT_PATH: ${{ env.GITHUB_EVENT_PATH }} 22 | GITHUB_TOKEN: ${{ secrets.PR_AUDITOR_TOKEN }} 23 | GITHUB_RUN_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} 24 | report_failure: 25 | needs: check-pr 26 | if: ${{ failure() }} 27 | uses: sourcegraph/workflows/.github/workflows/report-job-failure.yml@main 28 | secrets: inherit 29 | -------------------------------------------------------------------------------- /.github/workflows/release-docker.yml: -------------------------------------------------------------------------------- 1 | name: Release Docker 2 | on: 3 | push: 4 | branches: 5 | - main 6 | tags: ["*"] 7 | jobs: 8 | publish: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: 13 | fetch-depth: 0 14 | - uses: actions/setup-java@v3 15 | with: 16 | distribution: 'temurin' 17 | java-version: 8 18 | cache: 'sbt' 19 | - uses: sbt/setup-sbt@v1 20 | - uses: docker/setup-buildx-action@v1 21 | - name: Login to DockerHub 22 | uses: docker/login-action@v1 23 | with: 24 | username: ${{ secrets.DOCKER_USERNAME }} 25 | password: ${{ secrets.DOCKER_PASSWORD }} 26 | - run: sbt cli/dockerBuildAndPush 27 | -------------------------------------------------------------------------------- /.github/workflows/release-maven.yml: -------------------------------------------------------------------------------- 1 | name: Release Maven Central 2 | on: 3 | push: 4 | branches: [main] 5 | tags: ["*"] 6 | jobs: 7 | publish: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | with: 12 | fetch-depth: 0 13 | - uses: actions/setup-java@v3 14 | with: 15 | distribution: 'temurin' 16 | java-version: 8 17 | cache: 'sbt' 18 | - uses: sbt/setup-sbt@v1 19 | - name: Publish ${{ github.ref }} 20 | run: sbt ci-release 21 | env: 22 | PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} 23 | PGP_SECRET: ${{ secrets.PGP_SECRET }} 24 | SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} 25 | SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} 26 | -------------------------------------------------------------------------------- /.github/workflows/sourcegraph.yml: -------------------------------------------------------------------------------- 1 | name: Sourcegraph 2 | on: 3 | push: 4 | branches: ["main"] 5 | tags: ["v*"] 6 | pull_request: 7 | branches: ["*"] 8 | 9 | jobs: 10 | scip: 11 | runs-on: ubuntu-latest 12 | name: "Upload SCIP" 13 | steps: 14 | - uses: actions/checkout@v3 15 | with: 16 | fetch-depth: 0 17 | 18 | - uses: actions/setup-java@v3 19 | with: 20 | distribution: "temurin" 21 | java-version: 8 22 | cache: "sbt" 23 | 24 | - uses: sbt/setup-sbt@v1 25 | 26 | - name: Publish CLI locally 27 | run: sbt publishLocal dumpScipJavaVersion 28 | 29 | - name: Produce SCIP data of scip-java repository 30 | run: sbt -Dscip-java-version=$(cat VERSION) sourcegraphCompile 31 | 32 | - name: Upload index.scip 33 | uses: actions/upload-artifact@master 34 | with: 35 | path: target/sbt-sourcegraph/index.scip 36 | name: index.scip 37 | if-no-files-found: error 38 | 39 | - name: Install src 40 | run: yarn global add @sourcegraph/src 41 | 42 | - name: Upload sourcegraph data 43 | run: sbt -Dscip-java-version=$(cat VERSION) sourcegraphUpload 44 | env: 45 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 46 | SRC_ENDPOINT: https://sourcegraph.com/ 47 | SRC_ACCESS_TOKEN: ${{ secrets.SRC_ACCESS_TOKEN_DOTCOM }} 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | 4 | # sbt specific 5 | .cache 6 | .history 7 | .lib/ 8 | dist/* 9 | target/ 10 | lib_managed/ 11 | src_managed/ 12 | project/boot/ 13 | project/plugins/project/ 14 | .bloop 15 | 16 | _site/ 17 | 18 | # Scala-IDE specific 19 | .scala_dependencies 20 | .worksheet 21 | 22 | .idea 23 | 24 | # ENSIME specific 25 | .ensime_cache/ 26 | .ensime 27 | 28 | .metals/ 29 | metals.sbt 30 | metals/project/ 31 | 32 | .bsp 33 | 34 | .vscode/ 35 | 36 | local.* 37 | 38 | .DS_Store 39 | 40 | node_modules 41 | 42 | lib/core/metadata.js 43 | lib/core/MetadataBlog.js 44 | 45 | website/translated_docs 46 | website/build/ 47 | website/yarn.lock 48 | website/node_modules 49 | website/i18n/* 50 | 51 | project/metals.sbt 52 | out/ 53 | *.hnir 54 | test-report.json 55 | index.scip 56 | 57 | ./generated 58 | /sources 59 | bazel-bin 60 | bazel-scip-java 61 | bazel-out 62 | bazel-testlogs 63 | bazel-lsif-java 64 | 65 | VERSION 66 | 67 | semanticdb-gradle-plugin/gradle 68 | aspects/scip_java.bzl 69 | -------------------------------------------------------------------------------- /.jvmopts: -------------------------------------------------------------------------------- 1 | -Xss2m 2 | -Xms1G 3 | -Xmx4G 4 | -Dfile.encoding=UTF-8 5 | -------------------------------------------------------------------------------- /.scalafix.conf: -------------------------------------------------------------------------------- 1 | rules = [ 2 | OrganizeImports, 3 | ] 4 | 5 | ExplicitResultTypes.rewriteStructuralTypesToNamedSubclass = false 6 | 7 | OrganizeImports.groupedImports = Explode 8 | OrganizeImports.expandRelative = true 9 | OrganizeImports.removeUnused = true 10 | OrganizeImports.groups = [ 11 | "re:javax?\\." 12 | "scala." 13 | "scala.meta." 14 | "*" 15 | ] 16 | -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | version = "2.7.5" 2 | assumeStandardLibraryStripMargin = true 3 | docstrings.style = Asterisk 4 | docstrings.wrap = "yes" 5 | project.git = true 6 | align.preset = none 7 | align.stripMargin = true 8 | newlines.source=unfold 9 | project.excludeFilters = [ 10 | "tests/snapshots/src/main/generated" 11 | ] 12 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | golang 1.17.5 2 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sourcegraph/scip-java/ac4b5c7a0bcf11a531d2558d35b2169ff72695b5/BUILD -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing guide 2 | 3 | See https://sourcegraph.github.io/scip-java/docs/contributing.html 4 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM eclipse-temurin:17 2 | 3 | RUN apt-get update && apt-get install --yes jq wget curl zip unzip git python3 python3-pip autoconf automake libtool build-essential libtool make g++ 4 | 5 | WORKDIR /workdir 6 | 7 | COPY ./bin/docker-setup.sh . 8 | RUN ./docker-setup.sh 9 | 10 | 11 | ENV PATH=/opt/maven/bin:${PATH} 12 | ENV PATH=/opt/gradle/bin:${PATH} 13 | ENV PATH=/root/.local/share/coursier/bin:${PATH} 14 | 15 | ENV JAVA_TOOL_OPTIONS="-XX:MaxRAMPercentage=80.0 -XX:+UseContainerSupport" 16 | RUN git config --global --add safe.directory * 17 | 18 | COPY . . 19 | 20 | RUN sbt publishLocal dumpScipJavaVersion 21 | RUN mkdir -p /app && coursier bootstrap "com.sourcegraph:scip-java_2.13:$(cat VERSION)" -f -o /app/scip-java -M com.sourcegraph.scip_java.ScipJava 22 | 23 | COPY ./bin/scip-java-docker-script.sh /usr/bin/scip-java 24 | 25 | WORKDIR /sources 26 | 27 | RUN rm -rf /workdir 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java, Scala, and Kotlin indexer for [SCIP](https://github.com/sourcegraph/scip) ![](https://img.shields.io/badge/status-development-green?style=flat) 2 | 3 | | Documentation | Link | 4 | | -------------------- | ---------------------------------------------------------------------- | 5 | | Landing page | https://sourcegraph.github.io/scip-java | 6 | | Getting started | https://sourcegraph.github.io/scip-java/docs/getting-started.html | 7 | | Manual configuration | https://sourcegraph.github.io/scip-java/docs/manual-configuration.html | 8 | | Contributing | https://sourcegraph.github.io/scip-java/docs/contributing.html | 9 | | Design | https://sourcegraph.github.io/scip-java/docs/design.html | 10 | -------------------------------------------------------------------------------- /WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "scip_java_tests") 2 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 3 | 4 | ############## 5 | # Bazel stdlib 6 | ############## 7 | # To update this version, copy-paste instructions from https://github.com/bazelbuild/bazel-skylib/releases 8 | http_archive( 9 | name = "bazel_skylib", 10 | sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c", 11 | urls = [ 12 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", 13 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz", 14 | ], 15 | ) 16 | 17 | ########## 18 | # Protobuf 19 | ########## 20 | # To update this version, copy-paste instructions from https://github.com/bazelbuild/rules_proto/releases 21 | http_archive( 22 | name = "rules_proto", 23 | sha256 = "e017528fd1c91c5a33f15493e3a398181a9e821a804eb7ff5acdd1d2d6c2b18d", 24 | strip_prefix = "rules_proto-4.0.0-3.20.0", 25 | urls = [ 26 | "https://github.com/bazelbuild/rules_proto/archive/refs/tags/4.0.0-3.20.0.tar.gz", 27 | ], 28 | ) 29 | load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains") 30 | rules_proto_dependencies() 31 | rules_proto_toolchains() 32 | 33 | ############## 34 | # JVM External 35 | ############## 36 | # To update this version, copy-paste instructions from https://github.com/bazelbuild/rules_jvm_external/releases 37 | RULES_JVM_EXTERNAL_TAG = "4.2" 38 | RULES_JVM_EXTERNAL_SHA = "cd1a77b7b02e8e008439ca76fd34f5b07aecb8c752961f9640dea15e9e5ba1ca" 39 | http_archive( 40 | name = "rules_jvm_external", 41 | strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG, 42 | sha256 = RULES_JVM_EXTERNAL_SHA, 43 | url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG, 44 | ) 45 | load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps") 46 | rules_jvm_external_deps() 47 | load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup") 48 | rules_jvm_external_setup() 49 | load("@rules_jvm_external//:defs.bzl", "maven_install") 50 | maven_install( 51 | artifacts = [ 52 | "com.google.protobuf:protobuf-java:3.15.6", 53 | "com.google.protobuf:protobuf-java-util:3.15.6", 54 | "org.projectlombok:lombok:1.18.22", 55 | ], 56 | repositories = [ 57 | "https://repo1.maven.org/maven2", 58 | ], 59 | ) 60 | -------------------------------------------------------------------------------- /bin/coursier: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sourcegraph/scip-java/ac4b5c7a0bcf11a531d2558d35b2169ff72695b5/bin/coursier -------------------------------------------------------------------------------- /bin/docker-setup.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eux 3 | curl -fLo /usr/local/bin/coursier https://github.com/coursier/coursier/releases/download/v2.1.5/coursier 4 | chmod +x /usr/local/bin/coursier 5 | coursier setup --yes --apps coursier,sbt 6 | 7 | curl -fLo maven.zip https://archive.apache.org/dist/maven/maven-3/3.9.1/binaries/apache-maven-3.9.1-bin.zip 8 | unzip -d /opt/maven maven.zip 9 | rm maven.zip 10 | mv /opt/maven/*/* /opt/maven 11 | 12 | curl -fLo gradle.zip https://services.gradle.org/distributions/gradle-7.6.1-bin.zip 13 | unzip -d /opt/gradle gradle.zip 14 | rm gradle.zip 15 | mv /opt/gradle/*/* /opt/gradle 16 | 17 | # pre-install JDK for all major versions 18 | for JVM_VERSION in 21 17 11 8 19 | do 20 | coursier java --jvm $JVM_VERSION --jvm-index https://github.com/coursier/jvm-index/blob/master/index.json -- -version 21 | done 22 | -------------------------------------------------------------------------------- /bin/packagehub.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | /packagehub --host 0.0.0.0 --port $PORT --src /src --coursier /coursier --postgres.username=$DB_USER --postgres.password=$DB_PASS --postgres.url=$DB_URL 3 | -------------------------------------------------------------------------------- /bin/scip-java-docker-script.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Wrapper script for `scip-java`, which automatically picks up the correct JVM 3 | # version. It assumes that `coursier` is available on the `$PATH` and that the 4 | # `scip-java` binary is already installed at `/app/scip-java/bin/scip-java`. 5 | set -eu 6 | JVM_VERSION="${JVM_VERSION:-21,17,11,8}" 7 | FILE="$PWD/lsif-java.json" 8 | if test -f "$FILE"; then 9 | FROM_CONFIG=$(jq -r '.jvm' "$FILE") 10 | if [ "$FROM_CONFIG" != "null" ]; then 11 | JVM_VERSION="$FROM_CONFIG" 12 | fi 13 | fi 14 | 15 | JVM_VERSIONS=$(echo $JVM_VERSION | tr "," "\n") 16 | 17 | LAST_CODE="-1" 18 | 19 | ARGS=$@ 20 | 21 | for JVM_VERSION in $JVM_VERSIONS 22 | do 23 | if [ "$LAST_CODE" != "0" ]; then 24 | echo "Using JVM version '$JVM_VERSION'" 25 | 26 | if [ "$JVM_VERSION" = "17" ] || [ "$JVM_VERSION" = "21" ]; then 27 | export JAVA_OPTS="--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED" 28 | else 29 | export JAVA_OPTS="" 30 | fi 31 | eval "$(coursier java --jvm "$JVM_VERSION" --env --jvm-index https://github.com/coursier/jvm-index/blob/master/index.json)" 32 | 33 | java -version 34 | if /app/scip-java "$@"; then 35 | LAST_CODE="0" 36 | else 37 | LAST_CODE=$? 38 | fi 39 | 40 | fi 41 | done 42 | 43 | exit $LAST_CODE 44 | -------------------------------------------------------------------------------- /docs/benchmarks.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: benchmarks 3 | title: Benchmarks 4 | --- 5 | 6 | The repository contains benchmarks to measure the overhead of the SemanticDB 7 | compiler plugin. 8 | 9 | ``` 10 | $ sbt 11 | ... 12 | sbt:root> bench/jmh:run -i 10 -wi 10 -f1 -t1 13 | ... 14 | [info] Benchmark (lib) Mode Cnt Score Error Units 15 | [info] CompileBench.compile guava ss 10 2291.036 ± 243.428 ms/op 1x 16 | [info] CompileBench.compileSemanticdb guava ss 10 3444.978 ± 408.569 ms/op 1.5x 17 | [info] CompileBench.compile bytebuddy ss 10 1819.150 ± 191.530 ms/op 1x 18 | [info] CompileBench.compileSemanticdb bytebuddy ss 10 2641.590 ± 203.537 ms/op 1.45x 19 | ``` 20 | 21 | - Date: Monday 15 Feb 2021. 22 | - Hardware: MacBook Pro (16-inch, 2019), 2,6 GHz 6-Core Intel Core i7, 32 GB 23 | 2667 MHz DDR4. 24 | - Interpretation: enabling the SemanticDB compiler plugin slows down normal 25 | compilation by 45-50%. 26 | - Recommendation: do not enable the SemanticDB compiler plugin during local 27 | edit-and-test workflows. The compiler plugin is primarily intended to be 28 | enabled in custom CI jobs to upload SCIP indexes. 29 | -------------------------------------------------------------------------------- /docs/design.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: design 3 | title: Design 4 | --- 5 | 6 | This project is implemented as a 7 | [Java compiler plugin](https://docs.oracle.com/en/java/javase/11/docs/api/jdk.compiler/com/sun/source/util/Plugin.html) 8 | that generates one 9 | [SemanticDB](https://scalameta.org/docs/semanticdb/specification.html) file for 10 | every `*.java` source file. After compilation completes, the SemanticDB files 11 | are processed to produce SCIP. 12 | 13 | ![A three stage pipeline that starts with a list of Java sources, creates a list of SemanticDB files that then become a single SCIP index.](assets/semanticdb-javac-pipeline.svg) 14 | 15 | ### Why Java compiler plugin? 16 | 17 | There are several benefits to implementing scip-java as a compiler plugin: 18 | 19 | - **Simple installation**: compiler plugins are enabled with the `-Xplugin` 20 | compiler option. All Java build tools support a way to customize compiler 21 | options, simplifying installation. 22 | - **Language fidelity**: by using the Java compiler to produce semantic 23 | information, we ensure that the produced SCIP data is accurate even as new 24 | Java language versions with new language features are released. 25 | - **Environment fidelity**: by hooking into the compilation process of the build 26 | tool, we minimize the risk of diverging from the CI build environment such as 27 | installed system dependencies, custom compiler options and custom annotation 28 | processors. 29 | 30 | ### Why SemanticDB? 31 | 32 | SemanticDB is Protobuf schema for information about symbols and types in Java 33 | programs, Scala programs and other languages. There are several benefits to 34 | using SemanticDB as an intermediary representation for SCIP: 35 | 36 | - **Simplicity**: It's easy to translate a single Java source file into a single 37 | SemanticDB file inside a compiler plugin. It's more complicated to produce 38 | SCIP because compiler plugins does not have access to a project-wide context, 39 | which is necessary to produce accurate definitions and hovers in multi-module 40 | projects with external library dependencies. 41 | - **Performance**: SemanticDB is fast to write and read. Each compilation unit 42 | can be processed independently to keep memory usage low. The final conversion 43 | from SemanticDB to SCIP can be safely parallelized. 44 | - **Cross-language**: SemanticDB has a 45 | [spec](https://scalameta.org/docs/semanticdb/specification.html) for Java and 46 | Scala enabling cross-language navigation in hybrid Java/Scala codebases. 47 | - **Cross-repository**: Compiler plugins have access to both source code and the 48 | classpath (compiled bytecode of upstream dependencies). SemanticDB has been 49 | designed so that it's also possible to generate spec-compliant symbols from 50 | the classpath alone (no source code) and from the syntax tree of an individual 51 | source file (no classpath). This flexibility allows the 52 | [Metals](https://scalameta.org/metals/) language server to index codebases 53 | from a variety of different inputs, and will be helpful for scip-java in the 54 | future to unblock cross-repository navigation. 55 | -------------------------------------------------------------------------------- /examples/bazel-example/.bazelversion: -------------------------------------------------------------------------------- 1 | 5.2.0 2 | -------------------------------------------------------------------------------- /examples/bazel-example/.gitignore: -------------------------------------------------------------------------------- 1 | bazel-bazel-example 2 | aspects/scip_java.bzl 3 | -------------------------------------------------------------------------------- /examples/bazel-example/aspects/BUILD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sourcegraph/scip-java/ac4b5c7a0bcf11a531d2558d35b2169ff72695b5/examples/bazel-example/aspects/BUILD -------------------------------------------------------------------------------- /examples/bazel-example/src/main/java/example/BUILD: -------------------------------------------------------------------------------- 1 | # We import the custom `java_library` implementation that automatically adds the 2 | # SemanticDB compiler plugin based on the presence of the flag 3 | # `--@scip_java//semanticdb-javac:enabled=true`. By default, this java_library 4 | # rule works just like the official java_library rule. Feel free to copy-paste 5 | # the `semanticdb:defs.bzl` file and adapt to your needs. This example is only 6 | # for demonstration purposes. 7 | load("@scip_java//semanticdb-javac:defs.bzl", "java_library") 8 | 9 | package( 10 | default_visibility = ["//visibility:public"], 11 | ) 12 | 13 | java_library( 14 | name = "example", 15 | srcs = ["Example.java"], 16 | deps = [ 17 | "@maven//:com_google_guava_guava", 18 | ], 19 | ) 20 | -------------------------------------------------------------------------------- /examples/bazel-example/src/main/java/example/Example.java: -------------------------------------------------------------------------------- 1 | package example; 2 | import com.google.common.util.concurrent.Futures; 3 | 4 | public class Example { 5 | public static void hello() { 6 | System.out.println(Futures.immediateCancelledFuture()); 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /examples/bazel-example/src/main/java/source-generator-example/Animal.java: -------------------------------------------------------------------------------- 1 | 2 | import com.google.auto.value.AutoValue; 3 | 4 | @AutoValue 5 | abstract class Animal { 6 | static Animal create(String name, int numberOfLegs) { 7 | return new AutoValue_Animal(name, numberOfLegs); 8 | } 9 | 10 | abstract String name(); 11 | abstract int numberOfLegs(); 12 | } 13 | -------------------------------------------------------------------------------- /examples/bazel-example/src/main/java/source-generator-example/BUILD: -------------------------------------------------------------------------------- 1 | load("@scip_java//semanticdb-javac:defs.bzl", "java_library") 2 | load("@rules_java//java:defs.bzl", "java_plugin") 3 | 4 | package( 5 | default_visibility = ["//visibility:public"], 6 | ) 7 | 8 | java_library( 9 | name = "animal", 10 | srcs = ["Animal.java"], 11 | deps = [ 12 | ":autovalue", 13 | ], 14 | ) 15 | 16 | java_plugin( 17 | name = "autovalue_plugin", 18 | processor_class = "com.google.auto.value.processor.AutoValueProcessor", 19 | deps = [ 20 | "@maven//:com_google_auto_value_auto_value", 21 | ], 22 | ) 23 | 24 | java_library( 25 | name = "autovalue", 26 | exported_plugins = [ 27 | ":autovalue_plugin", 28 | ], 29 | neverlink = 1, 30 | exports = [ 31 | "@maven//:com_google_auto_value_auto_value", 32 | ], 33 | ) 34 | 35 | -------------------------------------------------------------------------------- /examples/bazel-example/src/main/java/srcjar_example/BUILD: -------------------------------------------------------------------------------- 1 | genrule( 2 | name = "generated-srcjar", 3 | outs = ["sources.srcjar"], 4 | cmd = "echo 'package com.testing; public class Bar {};' > Bar.java && jar cf $(@) Bar.java", 5 | ) 6 | 7 | genrule( 8 | name = "empty-srcjar", 9 | outs = ["empty.srcjar"], 10 | cmd = "touch test.txt && zip $(@) test.txt && zip -d $(@) test.txt", 11 | ) 12 | 13 | java_library( 14 | name = "testing", 15 | srcs = [ 16 | "Foo.java", 17 | ":generated-srcjar", 18 | ":empty-srcjar" 19 | ], 20 | ) 21 | 22 | java_library( 23 | name = "other_library", 24 | srcs = [ 25 | "Baz.java", # create a new file in source at test/Baz.java, alongside test/Foo.java 26 | ":generated-srcjar", 27 | ], 28 | ) 29 | 30 | java_test( 31 | name = "testing_test", 32 | srcs = [ 33 | "Foo.java", 34 | ":generated-srcjar", 35 | ], 36 | test_class = "Foo", 37 | ) 38 | -------------------------------------------------------------------------------- /examples/bazel-example/src/main/java/srcjar_example/Baz.java: -------------------------------------------------------------------------------- 1 | package com.testing; 2 | 3 | public class Baz { 4 | public Bar baz(Bar value) { 5 | return value; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/bazel-example/src/main/java/srcjar_example/Foo.java: -------------------------------------------------------------------------------- 1 | // testing/Foo.java 2 | package com.testing; 3 | 4 | public class Foo { 5 | public Bar foo(Bar value) { 6 | return value; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/maven-example/src/main/java/App.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | /** 4 | * Hello world! 5 | * 6 | */ 7 | public class App 8 | { 9 | public static void main( String[] args ) 10 | { 11 | System.out.println( "Hello World!" ); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/maven-example/src/test/java/AppTest.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Unit test for simple App. 9 | */ 10 | public class AppTest 11 | { 12 | /** 13 | * Rigorous Test :-) 14 | */ 15 | @Test 16 | public void shouldAnswerWithTrue() 17 | { 18 | assertTrue( true ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /maven-plugin/src/main/resources/META-INF/maven/plugin.template.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Sourcegraph scip-java Maven plugin 7 | A Maven plugin which exports your project's dependencies in a format scip-java can understand 8 | com.sourcegraph 9 | maven-plugin 10 | @VERSION@ 11 | sourcegraph 12 | false 13 | true 14 | 1.8 15 | 3.9.5 16 | 17 | 18 | sourcegraphDependencies 19 | false 20 | true 21 | false 22 | false 23 | false 24 | true 25 | generate-resources 26 | com.sourcegraph.maven.DependencyWriterMojo 27 | java 28 | per-lookup 29 | once-per-session 30 | test 31 | true 32 | 33 | 34 | project 35 | org.apache.maven.project.MavenProject 36 | true 37 | false 38 | The maven project. 39 | 40 | 41 | targetRoot 42 | java.lang.String 43 | false 44 | true 45 | Location where `dependencies.txt` file will be written (should match the Semanticdb targetroot option) 46 | 47 | 48 | 49 | ${project} 50 | ${session.executionRootDirectory}/target/semanticdb-targetroot 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.10.10 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.14") 2 | addSbtPlugin("se.marcuslonnberg" % "sbt-docker" % "1.9.0") 3 | addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.10") 4 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0") 5 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.6") 6 | addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.5.2") 7 | addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.0") 8 | addSbtPlugin("com.thesamet" % "sbt-protoc" % "1.0.6") 9 | addSbtPlugin("com.sourcegraph" % "sbt-sourcegraph" % "0.4.3") 10 | addSbtPlugin("com.lightbend.sbt" % "sbt-java-formatter" % "0.6.1") 11 | addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3") 12 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0") 13 | addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") 14 | // sbt-jdi-tools appears to fix an error related to this message: 15 | // [error] (plugin / Compile / compileIncremental) java.lang.NoClassDefFoundError: com/sun/tools/javac/code/Symbol 16 | addSbtPlugin("org.scala-debugger" % "sbt-jdi-tools" % "1.1.1") 17 | 18 | libraryDependencies ++= 19 | List("com.thesamet.scalapb" %% "compilerplugin" % "0.11.11") 20 | 21 | ThisBuild / libraryDependencySchemes ++= 22 | Seq("org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always) 23 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/renovate", 3 | "extends": [ 4 | "github>sourcegraph/renovate-config" 5 | ], 6 | "semanticCommits": false 7 | } 8 | -------------------------------------------------------------------------------- /sbt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | set -eu 3 | ./bin/coursier launch --jvm 11 sbt 4 | -------------------------------------------------------------------------------- /scip-java-proto/src/main/protobuf/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_java//java:defs.bzl", "java_proto_library") 2 | load("@rules_proto//proto:defs.bzl", "proto_library") 3 | 4 | package( 5 | default_visibility = ["//visibility:public"], 6 | ) 7 | 8 | java_proto_library( 9 | name = "scip_java_proto", 10 | deps = [":scip_proto"], 11 | ) 12 | 13 | proto_library( 14 | name = "scip_proto", 15 | srcs = ["scip.proto"], 16 | ) 17 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/io/AbsolutePath.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.io 2 | 3 | import java.nio.file.Path 4 | import java.nio.file.Paths 5 | 6 | object AbsolutePath { 7 | def systemWorkingDirectory: Path = Paths.get(".").toAbsolutePath.normalize() 8 | def of(path: Path): Path = of(path, systemWorkingDirectory) 9 | def of(path: Path, cwd: Path): Path = 10 | if (path.isAbsolute) 11 | path 12 | else if (cwd.isAbsolute) 13 | cwd.resolve(path) 14 | else 15 | systemWorkingDirectory.resolve(cwd).resolve(path) 16 | } 17 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/io/AutoDeletedFile.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.io 2 | 3 | import java.nio.charset.StandardCharsets 4 | import java.nio.file.Files 5 | import java.nio.file.Path 6 | import java.nio.file.StandardOpenOption 7 | 8 | import scala.util.Using.Releasable 9 | 10 | class AutoDeletedFile private ( 11 | val path: Path, 12 | val oldContent: Option[Array[Byte]] 13 | ) 14 | 15 | object AutoDeletedFile { 16 | def fromPath(path: Path, newContent: String): AutoDeletedFile = { 17 | val oldContent = 18 | if (Files.isRegularFile(path)) 19 | Some(Files.readAllBytes(path)) 20 | else 21 | None 22 | Files.createDirectories(path.getParent) 23 | Files.write( 24 | path, 25 | newContent.getBytes(StandardCharsets.UTF_8), 26 | StandardOpenOption.CREATE, 27 | StandardOpenOption.TRUNCATE_EXISTING 28 | ) 29 | new AutoDeletedFile(path, oldContent) 30 | } 31 | implicit val releasableAutoDeletedFile: Releasable[AutoDeletedFile] = { 32 | file => 33 | file.oldContent match { 34 | case Some(oldBytes) => 35 | Files.write( 36 | file.path, 37 | oldBytes, 38 | StandardOpenOption.CREATE, 39 | StandardOpenOption.TRUNCATE_EXISTING 40 | ) 41 | case None => 42 | Files.deleteIfExists(file.path) 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/io/DeleteVisitor.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.io 2 | 3 | import java.io.IOException 4 | import java.nio.file.FileVisitResult 5 | import java.nio.file.Files 6 | import java.nio.file.Path 7 | import java.nio.file.SimpleFileVisitor 8 | import java.nio.file.attribute.BasicFileAttributes 9 | 10 | class DeleteVisitor(deleteFile: Path => Boolean = _ => true) 11 | extends SimpleFileVisitor[Path] { 12 | override def preVisitDirectory( 13 | dir: Path, 14 | attrs: BasicFileAttributes 15 | ): FileVisitResult = { 16 | if (!deleteFile(dir)) 17 | FileVisitResult.SKIP_SUBTREE 18 | else 19 | super.preVisitDirectory(dir, attrs) 20 | } 21 | override def visitFile( 22 | file: Path, 23 | attrs: BasicFileAttributes 24 | ): FileVisitResult = { 25 | if (deleteFile(file)) { 26 | Files.deleteIfExists(file) 27 | } 28 | super.visitFile(file, attrs) 29 | } 30 | 31 | override def postVisitDirectory( 32 | dir: Path, 33 | exc: IOException 34 | ): FileVisitResult = { 35 | val ls = Files.list(dir) 36 | try { 37 | if (!ls.iterator().hasNext) { 38 | Files.deleteIfExists(dir) 39 | } 40 | } finally { 41 | ls.close() 42 | } 43 | super.postVisitDirectory(dir, exc) 44 | } 45 | 46 | override def visitFileFailed( 47 | file: Path, 48 | exc: IOException 49 | ): FileVisitResult = { 50 | FileVisitResult.CONTINUE 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/ScipJava.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java 2 | 3 | import java.io.PrintStream 4 | 5 | import com.sourcegraph.scip_java.commands.IndexCommand 6 | import com.sourcegraph.scip_java.commands.IndexDependencyCommand 7 | import com.sourcegraph.scip_java.commands.IndexSemanticdbCommand 8 | import com.sourcegraph.scip_java.commands.SnapshotCommand 9 | import com.sourcegraph.scip_java.commands.SnapshotLsifCommand 10 | import moped.cli.Application 11 | import moped.cli.CommandParser 12 | import moped.commands.HelpCommand 13 | import moped.commands.VersionCommand 14 | import moped.reporters.Tput 15 | 16 | object ScipJava { 17 | val app: Application = Application.fromName( 18 | binaryName = "scip-java", 19 | BuildInfo.version, 20 | List( 21 | CommandParser[HelpCommand], 22 | CommandParser[VersionCommand], 23 | CommandParser[IndexCommand], 24 | CommandParser[IndexSemanticdbCommand], 25 | CommandParser[IndexDependencyCommand], 26 | CommandParser[SnapshotCommand], 27 | CommandParser[SnapshotLsifCommand] 28 | ) 29 | ) 30 | def main(args: Array[String]): Unit = { 31 | app.runAndExitIfNonZero(args.toList) 32 | } 33 | 34 | def printHelp(out: PrintStream): Unit = { 35 | out.println("```text") 36 | out.println("$ scip-java index --help") 37 | val newApp = app 38 | .withTput(Tput.constant(100)) 39 | .withEnv(app.env.withStandardOutput(out)) 40 | newApp.run(List("index", "--help")) 41 | out.println("```") 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/ScipSymbol.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java 2 | 3 | import com.sourcegraph.scip_semanticdb.SymbolDescriptor 4 | import com.sourcegraph.semanticdb_javac.SemanticdbSymbols 5 | 6 | sealed abstract class ScipSymbol {} 7 | final case class LocalScipSymbol(identifier: String) extends ScipSymbol 8 | final case class GlobalScipSymbol( 9 | scheme: String, 10 | packageManager: String, 11 | packageName: String, 12 | packageVersion: String, 13 | descriptors: List[SymbolDescriptor] 14 | ) extends ScipSymbol 15 | 16 | object ScipSymbol { 17 | 18 | def parseOrThrowExceptionIfInvalid(scipSymbol: String): ScipSymbol = { 19 | if (scipSymbol.startsWith("local ")) { 20 | LocalScipSymbol(scipSymbol.stripPrefix("local ")) 21 | } else { 22 | scipSymbol.split(" ", 5) match { 23 | case Array( 24 | scheme, 25 | packageManager, 26 | packageName, 27 | packageVersion, 28 | descriptor 29 | ) => 30 | GlobalScipSymbol( 31 | scheme, 32 | packageManager, 33 | packageName, 34 | packageVersion, 35 | parseDescriptors(descriptor) 36 | ) 37 | case _ => 38 | throw new IllegalArgumentException( 39 | s"Invalid scip symbol: $scipSymbol" 40 | ) 41 | } 42 | } 43 | } 44 | 45 | private def parseDescriptors( 46 | semanticdbSymbol: String 47 | ): List[SymbolDescriptor] = { 48 | val descriptor = SymbolDescriptor.parseFromSymbol(semanticdbSymbol) 49 | if (descriptor.owner == SemanticdbSymbols.ROOT_PACKAGE) 50 | Nil 51 | else 52 | descriptor :: parseDescriptors(descriptor.owner) 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/BuildTool.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java.buildtools 2 | 3 | import java.nio.file.Files 4 | import java.nio.file.Path 5 | 6 | import com.sourcegraph.scip_java.commands.IndexCommand 7 | import os.CommandResult 8 | 9 | /** 10 | * A build tool such as Gradle, Maven or Bazel. 11 | */ 12 | abstract class BuildTool(val name: String, index: IndexCommand) { 13 | def isHidden: Boolean = false 14 | final def sourceroot: Path = index.workingDirectory 15 | def usedInCurrentDirectory(): Boolean 16 | def generateScip(): Int 17 | } 18 | 19 | object BuildTool { 20 | def all(index: IndexCommand): List[BuildTool] = 21 | // We don't support Bazel for auto-indexing, but if it's 22 | // detected, we should at least give a meaningful error message 23 | autoOrdered(index) :+ new BazelBuildTool(index) 24 | 25 | def autoOrdered(index: IndexCommand): List[BuildTool] = 26 | List( 27 | // The order in this list is important - 28 | // first detected build tool will be used in `auto` mode 29 | // Bazel is missing because it isn't supported by auto-indexing 30 | 31 | // first as it indicates user's intent to use SCIP auto-indexing 32 | new ScipBuildTool(index), 33 | // Maven first, then Gradle, then SBT 34 | // To match the order indicated in IntelliJ Java and Scala developer surveys 2022: 35 | // 1. https://www.jetbrains.com/lp/devecosystem-2022/java/#which-build-systems-do-you-regularly-use-if-any- 36 | // 2. https://www.jetbrains.com/lp/devecosystem-2022/scala/#which-build-systems-do-you-regularly-use-if-any- 37 | new MavenBuildTool(index), 38 | new GradleBuildTool(index), 39 | new SbtBuildTool(index), 40 | new MillBuildTool(index) 41 | ) 42 | def allNames: String = 43 | all(IndexCommand()).filterNot(_.isHidden).map(_.name).mkString(", ") 44 | 45 | def generateScipFromTargetroot( 46 | generateSemanticdbResult: CommandResult, 47 | targetroot: Path, 48 | index: IndexCommand, 49 | buildKind: String = "" 50 | ): Int = { 51 | if (!Files.isDirectory(targetroot)) { 52 | generateSemanticdbResult.exitCode 53 | } else if (index.app.reporter.hasErrors()) { 54 | index.app.reporter.exitCode() 55 | } else if (generateSemanticdbResult.exitCode != 0) { 56 | generateSemanticdbResult.exitCode 57 | } else { 58 | index 59 | .indexSemanticdb 60 | .copy( 61 | output = index.finalOutput, 62 | targetroot = List(targetroot), 63 | packagehub = index.packagehub, 64 | buildKind = buildKind, 65 | app = index.app 66 | ) 67 | .run() 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/MavenBuildTool.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java.buildtools 2 | 3 | import java.nio.file.Files 4 | import java.nio.file.Path 5 | import java.nio.file.Paths 6 | 7 | import scala.collection.mutable.ListBuffer 8 | 9 | import com.sourcegraph.scip_java.Embedded 10 | import com.sourcegraph.scip_java.commands.IndexCommand 11 | import os.CommandResult 12 | 13 | class MavenBuildTool(index: IndexCommand) extends BuildTool("Maven", index) { 14 | 15 | override def usedInCurrentDirectory(): Boolean = 16 | Files.isRegularFile(index.workingDirectory.resolve("pom.xml")) 17 | 18 | override def generateScip(): Int = { 19 | BuildTool.generateScipFromTargetroot( 20 | generateSemanticdb(), 21 | index.finalTargetroot(defaultTargetroot), 22 | index 23 | ) 24 | } 25 | 26 | private def defaultTargetroot: Path = 27 | Paths.get("target", "semanticdb-targetroot") 28 | 29 | private def generateSemanticdb(): CommandResult = { 30 | TemporaryFiles.withDirectory(index) { tmp => 31 | val mvnw = index.workingDirectory.resolve("mvnw") 32 | val mavenScript = 33 | if (Files.isRegularFile(mvnw) && Files.isExecutable(mvnw)) 34 | mvnw.toString 35 | else { 36 | "mvn" 37 | } 38 | val start = System.nanoTime() 39 | val buildCommand = ListBuffer.empty[String] 40 | val executable = Embedded.customJavac( 41 | index.workingDirectory, 42 | index.finalTargetroot(defaultTargetroot), 43 | tmp, 44 | GradleJavaToolchains.isJavaAtLeast(SystemJavaVersion.detect(), "11") 45 | ) 46 | buildCommand ++= 47 | List( 48 | mavenScript, 49 | s"-Dmaven.compiler.useIncrementalCompilation=false", 50 | // NOTE(olafur) the square/javapoet repo sets compilerId to 'javac-with-javac', which appears to 51 | // override the '-Dmaven.compiler.executable' setting.. Forcing the compilerId to 'javac' fixes the 52 | // issue for this repo. 53 | s"-Dmaven.compiler.compilerId=javac", 54 | s"-Dmaven.compiler.executable=$executable", 55 | s"-Dmaven.compiler.fork=true" 56 | ) 57 | buildCommand ++= 58 | index.finalBuildCommand( 59 | List( 60 | s"--batch-mode", 61 | s"clean", 62 | // Default to the "verify" command, as recommended by the official docs 63 | // https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#usual-command-line-calls 64 | "verify", 65 | "-DskipTests" 66 | ) 67 | ) 68 | 69 | val exit = index.process(buildCommand) 70 | Embedded 71 | .reportUnexpectedJavacErrors(index.app.reporter, tmp) 72 | .getOrElse(exit) 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ScalaCompilerClassLoader.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java.buildtools 2 | // Copied from: https://github.com/scalameta/metals/blob/3c83447ec658f87fdccbfb3f0a39fca1cec4ef6e/metals/src/main/scala/scala/meta/internal/metals/PresentationCompilerClassLoader.scala 3 | 4 | /** 5 | * ClassLoader that is used to reflectively invoke the Scala compiler. 6 | * 7 | * The Scala compiler is compiled against the exact Scala versions of the 8 | * compiler while scip-java is only compiled with Scala 2.13. In order to 9 | * communicate between scip-java and multiple versions of the compiler, this 10 | * classloader shares a subset of Java classes that appear in method signatures 11 | * of the `scala.meta.pc.PresentationCompiler` class. 12 | */ 13 | class ScalaCompilerClassLoader(parent: ClassLoader) extends ClassLoader(null) { 14 | override def findClass(name: String): Class[_] = { 15 | val isShared = 16 | name.startsWith("org.eclipse.lsp4j") || name.startsWith("javax.") || 17 | name.startsWith("com.google.gson") || name.startsWith("scala.meta.pc") 18 | if (isShared) { 19 | parent.loadClass(name) 20 | } else { 21 | throw new ClassNotFoundException(name) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/ScalaVersion.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java.buildtools 2 | 3 | import java.nio.file.Path 4 | 5 | import com.sourcegraph.scip_java.BuildInfo 6 | 7 | object ScalaVersion { 8 | 9 | /** 10 | * Returns a best-effort guess for which Scala version to compile with the 11 | * given jar filename. 12 | * 13 | * The implementation of this method may seem hacky but it's the best approach 14 | * I can think of that solves this problem with the given constraints: 15 | * 16 | * - We can't assume scala-library.jar is on the classpath because Scala 17 | * libraries like `com.lihaoyi:geny` don't include an explicit dependency 18 | * on scala-library. See https://github.com/com-lihaoyi/geny/issues/32 19 | * - We want to support Scala 3, which uses the same scala-library as Scala 20 | * 2.13. 21 | * - We should only infer Scala versions that are supported by the 22 | * `org.scalameta:mtags` module, which we use to compile SemanticDB files. 23 | * Currently, mtags supports the latest patch releases of Scala 2.11, 24 | * 2.12, 2.13 and Scala 3. 25 | */ 26 | def inferFromJar(jar: Path): Option[String] = { 27 | val Scala3 = ".*_3\\b.*".r 28 | val Scala211 = ".*_2.11\\b.*".r 29 | val Scala212 = ".*_2.12\\b.*".r 30 | val Scala213 = ".*_2.13\\b.*".r 31 | // The official Scala 2 distribution doesn't use the standard _2.N suffix 32 | // So we add a special case for scala-{compiler,reflect,library} and scalap. 33 | val ScalaOfficial = 34 | ".*scala(p|-compiler|-reflect|-library)?-2.([^\\.]+).*.jar".r 35 | Option(jar.getFileName.toString).collect { 36 | case Scala3() => 37 | BuildInfo.scala3 38 | case Scala211() => 39 | BuildInfo.scala211 40 | case Scala212() => 41 | BuildInfo.scala212 42 | case Scala213() => 43 | BuildInfo.scala213 44 | case ScalaOfficial(_, "11") => 45 | BuildInfo.scala211 46 | case ScalaOfficial(_, "12") => 47 | BuildInfo.scala212 48 | case ScalaOfficial(_, "13") => 49 | BuildInfo.scala213 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/SystemJavaVersion.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java.buildtools 2 | 3 | import java.nio.file.Files 4 | 5 | import com.sourcegraph.scip_java.Embedded 6 | 7 | object SystemJavaVersion { 8 | // Returns the output of `System.getProperty("java.version")` from a fresh JVM 9 | // instance using the system JVM installation. We can't use this process since 10 | // it may be running on a separate JVM process (that's the case when we run 11 | // `sbt test` in this build at least). 12 | def detect(): String = { 13 | val tmp = Files.createTempDirectory("java-version") 14 | val jar = Embedded.semanticdbJar(tmp) 15 | try { 16 | os.proc( 17 | "java", 18 | "-cp", 19 | jar.toString(), 20 | "com.sourcegraph.semanticdb_javac.PrintJavaVersion" 21 | ) 22 | .call() 23 | .out 24 | .text() 25 | .trim() 26 | } finally { 27 | Files.deleteIfExists(jar) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/buildtools/TemporaryFiles.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java.buildtools 2 | 3 | import java.nio.file.Files 4 | import java.nio.file.Path 5 | 6 | import com.sourcegraph.io.DeleteVisitor 7 | import com.sourcegraph.scip_java.commands.IndexCommand 8 | 9 | object TemporaryFiles { 10 | def withDirectory[T](index: IndexCommand)(fn: Path => T): T = { 11 | index.temporaryDirectory match { 12 | case Some(tmp) => 13 | fn(tmp) 14 | case None => 15 | val tmp = Files.createTempDirectory("scip-java") 16 | try fn(tmp) 17 | finally { 18 | if (index.cleanup) { 19 | Files.walkFileTree(tmp, new DeleteVisitor()) 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/commands/CommentSyntax.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java.commands 2 | 3 | case class CommentSyntax(value: String) { 4 | private val map = 5 | value 6 | .split("\\s+") 7 | .map(_.split(",")) 8 | .collect { case Array(a, b) => 9 | a -> b 10 | } 11 | .toMap 12 | def extensionSyntax(fileExtension: String): String = 13 | map.getOrElse(fileExtension, "//") 14 | } 15 | object CommentSyntax { 16 | val default = CommentSyntax("py,# sql,-- yaml,# yml,#") 17 | implicit val codec = moped.macros.deriveCodec(default) 18 | } 19 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_java/commands/SnapshotLsifCommand.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_java.commands 2 | 3 | import java.nio.file.Path 4 | import java.nio.file.Paths 5 | 6 | import moped.annotations.CommandName 7 | import moped.annotations.Inline 8 | import moped.annotations.PositionalArguments 9 | import moped.cli.Application 10 | import moped.cli.Command 11 | import moped.cli.CommandParser 12 | 13 | @CommandName("snapshot-lsif") 14 | case class SnapshotLsifCommand( 15 | @Inline() app: Application = Application.default, 16 | @PositionalArguments() input: List[Path] = List(Paths.get("dump.lsif")) 17 | ) extends Command { 18 | def run(): Int = { 19 | app.error( 20 | "this command is no longer supported. To run this command, downgrade to scip-java v0.8.14 and try again." 21 | ) 22 | 1 23 | } 24 | 25 | } 26 | 27 | object SnapshotLsifCommand { 28 | val default = SnapshotLsifCommand() 29 | implicit val parser = CommandParser.derive(default) 30 | } 31 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_semanticdb/ConsolescipSemanticdbReporter.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb 2 | 3 | import java.io.PrintWriter 4 | import java.nio.file.NoSuchFileException 5 | 6 | import moped.cli.Application 7 | import moped.progressbars.InteractiveProgressBar 8 | 9 | /** 10 | * Console reporter for index-semanticdb command. 11 | */ 12 | class ConsoleScipSemanticdbReporter(app: Application) 13 | extends ScipSemanticdbReporter { 14 | 15 | val renderer = new ScipSemanticdbProgressRenderer 16 | val progressbar = 17 | new InteractiveProgressBar( 18 | new PrintWriter(app.env.standardError), 19 | renderer, 20 | isDynamicPartEnabled = app.env.isProgressBarEnabled 21 | ) 22 | override def error(e: Throwable): Unit = { 23 | e match { 24 | case _: NoSuchFileException => 25 | app.reporter.error(s"no such file: ${e.getMessage}") 26 | case _ => 27 | e.printStackTrace(app.err) 28 | } 29 | } 30 | 31 | override def hasErrors: Boolean = app.reporter.hasErrors() 32 | override def startProcessing(taskSize: Int): Unit = { 33 | renderer.totalSize = taskSize 34 | progressbar.start() 35 | } 36 | override def processedOneItem(): Unit = { 37 | renderer.currentSize.incrementAndGet() 38 | } 39 | override def endProcessing(): Unit = { 40 | progressbar.stop() 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /scip-java/src/main/scala/com/sourcegraph/scip_semanticdb/ScipSemanticdbProgressRenderer.scala: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb 2 | 3 | import java.util.concurrent.atomic.AtomicInteger 4 | 5 | import moped.progressbars.ProgressRenderer 6 | import moped.progressbars.ProgressStep 7 | import org.typelevel.paiges.Doc 8 | 9 | /** 10 | * Progress bar for the scip-semanticdb command. 11 | */ 12 | class ScipSemanticdbProgressRenderer() extends ProgressRenderer { 13 | var totalSize = 0 14 | val currentSize = new AtomicInteger() 15 | override def renderStep(): ProgressStep = { 16 | if (totalSize < 100) 17 | return ProgressStep.empty 18 | 19 | val current = currentSize.get() 20 | val ratio = current.toDouble / totalSize 21 | val progress: Int = (ratio * 10).toInt 22 | val percentage: String = s"${(ratio * 100).toInt}%".padTo(4, ' ') 23 | val bars = ("#" * progress).padTo(10, ' ') 24 | val render = 25 | f"Generating SCIP... [$bars] $percentage $current%,.0f files processed" 26 | ProgressStep(static = Doc.empty, dynamic = Doc.text(render)) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /scip-semanticdb/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_proto_library") 2 | load("@rules_proto//proto:defs.bzl", "proto_library") 3 | 4 | package( 5 | default_visibility = ["//visibility:public"], 6 | ) 7 | 8 | java_binary( 9 | name = "bazel", 10 | main_class = "com.sourcegraph.scip_semanticdb.BazelBuildTool", 11 | runtime_deps = [ 12 | ":scip-semanticdb", 13 | ], 14 | ) 15 | 16 | java_library( 17 | name = "scip-semanticdb", 18 | srcs = glob(["src/main/java/**/*.java"]), 19 | deps = [ 20 | ":all_java_proto", 21 | "//scip-java-proto/src/main/protobuf:scip_java_proto", 22 | "//semanticdb-java", 23 | "//semanticdb-java/src/main/protobuf:semanticdb_java_proto", 24 | "@maven//:com_google_code_findbugs_jsr305", 25 | "@maven//:com_google_protobuf_protobuf_java", 26 | "@maven//:com_google_protobuf_protobuf_java_util", 27 | ], 28 | ) 29 | 30 | java_proto_library( 31 | name = "all_java_proto", 32 | deps = [":all_proto"], 33 | ) 34 | 35 | proto_library( 36 | name = "all_proto", 37 | srcs = glob(["src/main/protobuf/*.proto"]), 38 | ) 39 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/InputStreamBytes.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | 7 | public class InputStreamBytes { 8 | public static byte[] readAll(InputStream in) throws IOException { 9 | try { 10 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 11 | byte[] buffer = new byte[4096]; 12 | int nread; 13 | do { 14 | nread = in.read(buffer, 0, buffer.length); 15 | if (nread != -1) baos.write(buffer, 0, nread); 16 | } while (nread != -1); 17 | return baos.toByteArray(); 18 | } finally { 19 | in.close(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/JdkPackage.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | public class JdkPackage extends Package { 4 | public final String version; 5 | 6 | public JdkPackage(String version) { 7 | this.version = version; 8 | } 9 | 10 | @Override 11 | public String repoName() { 12 | return "jdk"; 13 | } 14 | 15 | @Override 16 | public String version() { 17 | return version; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return "JdkPackage{" + "version='" + version + '\'' + '}'; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/MarkupContent.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import com.sourcegraph.lsif_protocol.MarkupKind; 4 | 5 | public class MarkupContent { 6 | public final String value; 7 | public final MarkupKind kind; 8 | 9 | public MarkupContent(MarkupKind kind, String value) { 10 | this.value = value; 11 | this.kind = kind; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/MavenPackage.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import java.nio.file.Path; 4 | 5 | public class MavenPackage extends Package { 6 | public final Path jar; 7 | public final String groupId; 8 | public final String artifactId; 9 | public final String version; 10 | 11 | public MavenPackage(Path jar, String groupId, String artifactId, String version) { 12 | this.jar = jar; 13 | this.groupId = groupId; 14 | this.artifactId = artifactId; 15 | this.version = version; 16 | } 17 | 18 | public MavenPackage withJar(Path newJar) { 19 | return new MavenPackage(newJar, this.groupId, this.artifactId, this.version); 20 | } 21 | 22 | @Override 23 | public String repoName() { 24 | return String.format("maven/%s/%s", groupId, artifactId); 25 | } 26 | 27 | @Override 28 | public String version() { 29 | return version; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "MavenPackage{" 35 | + "jar=" 36 | + jar 37 | + ", groupId='" 38 | + groupId 39 | + '\'' 40 | + ", artifactId='" 41 | + artifactId 42 | + '\'' 43 | + ", version='" 44 | + version 45 | + '\'' 46 | + '}'; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/MessageOnlyException.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | /** 4 | * Exception that doesn't fill out the stack trace, it only prints out the message. 5 | * 6 | *

Use this exception if you want prettier console output without stack trace noise. 7 | */ 8 | public class MessageOnlyException extends Throwable { 9 | public MessageOnlyException(String message) { 10 | super(message); 11 | } 12 | 13 | @Override 14 | public synchronized Throwable fillInStackTrace() { 15 | return this; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/OperatingSystem.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | public class OperatingSystem { 4 | public static boolean isWindows() { 5 | return System.getProperty("os.name").startsWith("Windows"); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/Package.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | public abstract class Package { 4 | public static final Package EMPTY = 5 | new Package() { 6 | @Override 7 | public String repoName() { 8 | return "."; 9 | } 10 | 11 | @Override 12 | public String version() { 13 | return "."; 14 | } 15 | }; 16 | 17 | public abstract String repoName(); 18 | 19 | public abstract String version(); 20 | 21 | public final String scipTypedEncoding() { 22 | return "maven " + encode(repoName()) + " " + encode(version()); 23 | } 24 | 25 | private String encode(String value) { 26 | if (value.contains(" ")) { 27 | return "`" + value + "`"; 28 | } 29 | return value; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/RangeComparator.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import com.sourcegraph.semanticdb_javac.Semanticdb.Range; 4 | 5 | /** 6 | * Comparator that sorts SemanticDB ranges by appearance in the document. 7 | * 8 | *

We can't guarantee ordering of SymbolOccurrence in SemanticDB payloads so it's good to sort 9 | * them before processing. 10 | */ 11 | public class RangeComparator implements java.util.Comparator { 12 | 13 | @Override 14 | public int compare(Range r1, Range r2) { 15 | int byStartLine = Integer.compare(r1.getStartLine(), r2.getStartLine()); 16 | if (byStartLine != 0) { 17 | return byStartLine; 18 | } 19 | int byStartCharacter = Integer.compare(r1.getStartCharacter(), r2.getStartCharacter()); 20 | if (byStartCharacter != 0) { 21 | return byStartCharacter; 22 | } 23 | int byEndLine = Integer.compare(r1.getEndLine(), r2.getEndLine()); 24 | if (byEndLine != 0) { 25 | return byEndLine; 26 | } 27 | return Integer.compare(r1.getEndCharacter(), r2.getEndCharacter()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ResultIds.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | /** Utility to deal with a group of IDs for a result set, definition result and reference result. */ 4 | public class ResultIds { 5 | public final int resultSet; 6 | public final int definitionResult; 7 | public final int referenceResult; 8 | 9 | public ResultIds(int resultSet, int definitionResult, int referenceResult) { 10 | this.resultSet = resultSet; 11 | this.definitionResult = definitionResult; 12 | this.referenceResult = referenceResult; 13 | } 14 | 15 | public boolean isDefinitionDefined() { 16 | return definitionResult > 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ResultSets.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import com.sourcegraph.semanticdb_javac.SemanticdbSymbols; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | import java.util.Optional; 7 | import java.util.Set; 8 | import java.util.function.Function; 9 | 10 | /** Utility to deal with the creation of result sets. */ 11 | public class ResultSets implements Function { 12 | 13 | private final ScipWriter writer; 14 | private final Map globals; 15 | private final HashMap locals; 16 | private final Set exportedSymbols; 17 | private final Set localDefinitions; 18 | private final PackageTable packages; 19 | private final boolean isJdkRepo; 20 | 21 | public ResultSets( 22 | ScipWriter writer, 23 | Map globals, 24 | Set exportedSymbols, 25 | Set localDefinitions, 26 | PackageTable packages, 27 | ScipSemanticdbOptions options) { 28 | this.writer = writer; 29 | this.globals = globals; 30 | this.exportedSymbols = exportedSymbols; 31 | this.localDefinitions = localDefinitions; 32 | this.packages = packages; 33 | this.isJdkRepo = options.buildKind.equals("jdk"); 34 | locals = new HashMap<>(); 35 | } 36 | 37 | public ResultIds getOrInsertResultSet(String symbol) { 38 | boolean isLocal = SemanticdbSymbols.isLocal(symbol); 39 | Map cache = isLocal ? locals : globals; 40 | return cache.computeIfAbsent(symbol, this); 41 | } 42 | 43 | @Override 44 | public ResultIds apply(String symbol) { 45 | boolean isExportedSymbol = exportedSymbols.contains(symbol); 46 | boolean hasDefinitionResult = isExportedSymbol || localDefinitions.contains(symbol); 47 | int resultSet = writer.emitResultSet(); 48 | 49 | // Moniker 50 | Optional pkg = packages.packageForSymbol(symbol); 51 | if (pkg.isPresent() && pkg.get() instanceof JdkPackage && !isJdkRepo) { 52 | // Never export monikers for the JDK repo unless we're indexing the JDK repo. 53 | // Some Maven packages contain sources that redefine symbols like `java/lang/String#` 54 | // even if the the jar files don't contain `java/lang/String.class`. For example, 55 | // see the package com.google.gwt:gwt-user:2.9.0. 56 | // Related issue: https://github.com/sourcegraph/sourcegraph/issues/21058 57 | isExportedSymbol = false; 58 | } 59 | int monikerId = writer.emitMonikerVertex(symbol, hasDefinitionResult); 60 | writer.emitMonikerEdge(resultSet, monikerId); 61 | if (pkg.isPresent()) { 62 | packages.writeMonikerPackage(monikerId, pkg.get()); 63 | } 64 | 65 | int definitionId = hasDefinitionResult ? writer.emitDefinitionResult(resultSet) : -1; 66 | 67 | return new ResultIds(resultSet, definitionId, writer.emitReferenceResult(resultSet)); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipByteOutputStream.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.OutputStreamWriter; 5 | 6 | /** Wrapper around a ByteArrayOutputStream and OutputStreamWriter. */ 7 | public class ScipByteOutputStream { 8 | public final ByteArrayOutputStream output; 9 | public final OutputStreamWriter writer; 10 | 11 | public ScipByteOutputStream() { 12 | this.output = new ByteArrayOutputStream(); 13 | this.writer = new OutputStreamWriter(output); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipOutputFormat.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | /** 4 | * Whether to generate index.scip (JSON) or index.scip-protobuf (Protobuf). 5 | * 6 | *

The Protobuf format is experimental and currently only exists as a proof-of-concept. 7 | */ 8 | public enum ScipOutputFormat { 9 | GRAPH_NDJSON, 10 | GRAPH_PROTOBUF, 11 | TYPED_PROTOBUF, 12 | TYPED_NDJSON, 13 | UNKNOWN; 14 | 15 | public boolean isTyped() { 16 | return this == TYPED_NDJSON || this == TYPED_PROTOBUF; 17 | } 18 | 19 | public boolean isNewlineDelimitedJSON() { 20 | return this == GRAPH_NDJSON || this == TYPED_NDJSON; 21 | } 22 | 23 | public static ScipOutputFormat fromFilename(String name) { 24 | if (name.endsWith(".lsif")) return GRAPH_NDJSON; 25 | if (name.endsWith(".lsif-protobuf")) return GRAPH_PROTOBUF; 26 | if (name.endsWith(".scip")) return TYPED_PROTOBUF; 27 | if (name.endsWith(".scip.ndjson")) return TYPED_NDJSON; 28 | return UNKNOWN; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipOutputStream.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import com.google.protobuf.Descriptors.FieldDescriptor; 4 | import com.google.protobuf.util.JsonFormat; 5 | import com.google.protobuf.util.JsonFormat.Printer; 6 | import com.sourcegraph.lsif_protocol.LsifObject; 7 | import com.sourcegraph.lsif_protocol.LsifPosition; 8 | import java.io.IOException; 9 | import java.io.OutputStream; 10 | import java.nio.charset.StandardCharsets; 11 | import java.util.HashSet; 12 | import java.util.Set; 13 | import java.util.concurrent.ConcurrentLinkedDeque; 14 | import java.util.concurrent.atomic.AtomicBoolean; 15 | 16 | /** Low-level methods to write raw SCIP objects into the output stream. */ 17 | public class ScipOutputStream { 18 | private final ScipSemanticdbOptions options; 19 | private final OutputStream out; 20 | private final ConcurrentLinkedDeque buffer; 21 | private final AtomicBoolean isFlushing; 22 | private static final byte[] NEWLINE = "\n".getBytes(StandardCharsets.UTF_8); 23 | private final ThreadLocal baos = 24 | ThreadLocal.withInitial(ScipByteOutputStream::new); 25 | private final Printer jsonPrinter; 26 | 27 | public ScipOutputStream(ScipSemanticdbOptions options, OutputStream out) { 28 | this.options = options; 29 | this.out = out; 30 | buffer = new ConcurrentLinkedDeque<>(); 31 | isFlushing = new AtomicBoolean(false); 32 | 33 | Set fieldsToAlwaysInclude = 34 | new HashSet<>(LsifPosition.getDescriptor().getFields()); 35 | fieldsToAlwaysInclude.add(LsifObject.getDescriptor().findFieldByName("id")); 36 | jsonPrinter = 37 | JsonFormat.printer() 38 | .includingDefaultValueFields(fieldsToAlwaysInclude) 39 | .omittingInsignificantWhitespace(); 40 | } 41 | 42 | public void write(byte[] bytes) { 43 | if (bytes.length == 0) return; 44 | buffer.add(bytes); 45 | } 46 | 47 | public void writeLsifObject(LsifObject.Builder object) { 48 | ScipByteOutputStream b = baos.get(); 49 | b.output.reset(); 50 | try { 51 | switch (options.format) { 52 | case GRAPH_PROTOBUF: 53 | object.buildPartial().writeTo(b.output); 54 | break; 55 | case GRAPH_NDJSON: 56 | default: 57 | jsonPrinter.appendTo(object, b.writer); 58 | b.writer.flush(); 59 | break; 60 | } 61 | } catch (IOException e) { 62 | options.reporter.error(e); 63 | } 64 | write(b.output.toByteArray()); 65 | } 66 | 67 | public void flush() throws IOException { 68 | if (isFlushing.compareAndSet(false, true)) { 69 | byte[] bytes = buffer.poll(); 70 | while (bytes != null) { 71 | out.write(bytes); 72 | if (options.format.isNewlineDelimitedJSON()) { 73 | out.write(NEWLINE); 74 | } 75 | bytes = buffer.poll(); 76 | } 77 | out.flush(); 78 | isFlushing.set(false); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipProcessingException.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | public class ScipProcessingException extends Throwable { 4 | 5 | public ScipProcessingException(ScipTextDocument doc, Throwable cause) { 6 | super(doc.semanticdbPath.toString(), cause); 7 | } 8 | 9 | @Override 10 | public Throwable fillInStackTrace() { 11 | return this; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdbOptions.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import com.sourcegraph.lsif_protocol.LsifToolInfo; 4 | import java.nio.file.Path; 5 | import java.util.List; 6 | 7 | /** Configuration options to tweak the scip-semanticdb command. */ 8 | public class ScipSemanticdbOptions { 9 | 10 | public final List targetroots; 11 | public final Path output; 12 | public final Path sourceroot; 13 | public final ScipSemanticdbReporter reporter; 14 | public final LsifToolInfo toolInfo; 15 | public final String language; 16 | public final ScipOutputFormat format; 17 | public final boolean parallel; 18 | public final List packages; 19 | public final String buildKind; 20 | public final boolean emitInverseRelationships; 21 | public final boolean allowEmptyIndex; 22 | public final boolean allowExportingGlobalSymbolsFromDirectoryEntries; 23 | 24 | public ScipSemanticdbOptions( 25 | List targetroots, 26 | Path output, 27 | Path sourceroot, 28 | ScipSemanticdbReporter reporter, 29 | LsifToolInfo toolInfo, 30 | String language, 31 | ScipOutputFormat format, 32 | boolean parallel, 33 | List packages, 34 | String buildKind, 35 | boolean emitInverseRelationships, 36 | boolean allowEmptyIndex, 37 | boolean allowExportingGlobalSymbolsFromDirectoryEntries) { 38 | this.targetroots = targetroots; 39 | this.output = output; 40 | this.sourceroot = sourceroot; 41 | this.reporter = reporter; 42 | this.toolInfo = toolInfo; 43 | this.language = language; 44 | this.format = format; 45 | this.parallel = parallel; 46 | this.packages = packages; 47 | this.buildKind = buildKind; 48 | this.emitInverseRelationships = emitInverseRelationships; 49 | this.allowEmptyIndex = allowEmptyIndex; 50 | this.allowExportingGlobalSymbolsFromDirectoryEntries = 51 | allowExportingGlobalSymbolsFromDirectoryEntries; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/ScipSemanticdbReporter.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | /** 4 | * API to hook into the event stream of the scip-semanticdb command. 5 | * 6 | *

The scip-semanticdb command doesn't fail fast on the first error. Clients are expected to 7 | * handle errors through the error method. 8 | */ 9 | public abstract class ScipSemanticdbReporter { 10 | public void error(Throwable e) {} 11 | 12 | public void error(String message) { 13 | error(new MessageOnlyException(message)); 14 | } 15 | 16 | public void startProcessing(int taskSize) {} 17 | 18 | public void processedOneItem() {} 19 | 20 | public void endProcessing() {} 21 | 22 | public boolean hasErrors() { 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SemanticdbTreeVisitor.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import com.sourcegraph.semanticdb_javac.Semanticdb.*; 4 | 5 | public abstract class SemanticdbTreeVisitor { 6 | public void visitTree(Tree tree) { 7 | if (tree.hasApplyTree()) { 8 | this.visitApplyTree(tree.getApplyTree()); 9 | } else if (tree.hasFunctionTree()) { 10 | this.visitFunctionTree(tree.getFunctionTree()); 11 | } else if (tree.hasIdTree()) { 12 | this.visitIdTree(tree.getIdTree()); 13 | } else if (tree.hasLiteralTree()) { 14 | this.visitLiteralTree(tree.getLiteralTree()); 15 | } else if (tree.hasMacroExpansionTree()) { 16 | this.visitMacroExpansionTree(tree.getMacroExpansionTree()); 17 | } else if (tree.hasOriginalTree()) { 18 | this.visitOriginalTree(tree.getOriginalTree()); 19 | } else if (tree.hasSelectTree()) { 20 | this.visitSelectTree(tree.getSelectTree()); 21 | } else if (tree.hasTypeApplyTree()) { 22 | this.visitTypeApplyTree(tree.getTypeApplyTree()); 23 | } else if (tree.hasAnnotationTree()) { 24 | this.visitAnnotationTree(tree.getAnnotationTree()); 25 | } else if (tree.hasAssignTree()) { 26 | this.visitAssignTree(tree.getAssignTree()); 27 | } else if (tree.hasBinopTree()) { 28 | this.visitBinaryOperatorTree(tree.getBinopTree()); 29 | } 30 | } 31 | 32 | void visitApplyTree(ApplyTree tree) { 33 | visitTree(tree.getFunction()); 34 | for (Tree argument : tree.getArgumentsList()) { 35 | visitTree(argument); 36 | } 37 | } 38 | 39 | void visitFunctionTree(FunctionTree tree) { 40 | for (IdTree parameter : tree.getParametersList()) { 41 | visitIdTree(parameter); 42 | } 43 | visitTree(tree.getBody()); 44 | } 45 | 46 | void visitIdTree(IdTree tree) {} 47 | 48 | void visitLiteralTree(LiteralTree tree) {} 49 | 50 | void visitMacroExpansionTree(MacroExpansionTree tree) { 51 | visitTree(tree.getBeforeExpansion()); 52 | } 53 | 54 | void visitOriginalTree(OriginalTree tree) {} 55 | 56 | void visitSelectTree(SelectTree tree) { 57 | visitTree(tree.getQualifier()); 58 | visitIdTree(tree.getId()); 59 | } 60 | 61 | void visitTypeApplyTree(TypeApplyTree tree) { 62 | visitTree(tree.getFunction()); 63 | } 64 | 65 | void visitAnnotationTree(AnnotationTree tree) { 66 | for (Tree parameter : tree.getParametersList()) { 67 | visitTree(parameter); 68 | } 69 | } 70 | 71 | void visitAssignTree(AssignTree tree) { 72 | visitTree(tree.getLhs()); 73 | visitTree(tree.getRhs()); 74 | } 75 | 76 | void visitBinaryOperatorTree(BinaryOperatorTree tree) { 77 | visitTree(tree.getLhs()); 78 | visitTree(tree.getRhs()); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SemanticdbWalker.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.FileSystems; 5 | import java.nio.file.FileVisitResult; 6 | import java.nio.file.Files; 7 | import java.nio.file.Path; 8 | import java.nio.file.PathMatcher; 9 | import java.nio.file.SimpleFileVisitor; 10 | import java.nio.file.attribute.BasicFileAttributes; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** A file visitor that recursively collects all SemanticDB files in a given directory. */ 15 | public class SemanticdbWalker extends SimpleFileVisitor { 16 | private final ArrayList result; 17 | private final ScipSemanticdbOptions options; 18 | private final PathMatcher semanticdbPattern = 19 | FileSystems.getDefault().getPathMatcher("glob:**.semanticdb"); 20 | 21 | public SemanticdbWalker(ScipSemanticdbOptions options) { 22 | this.options = options; 23 | result = new ArrayList<>(); 24 | } 25 | 26 | @Override 27 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { 28 | if (semanticdbPattern.matches(file)) { 29 | result.add(file); 30 | } 31 | return super.visitFile(file, attrs); 32 | } 33 | 34 | @Override 35 | public FileVisitResult visitFileFailed(Path file, IOException exc) { 36 | options.reporter.error(exc); 37 | return FileVisitResult.CONTINUE; 38 | } 39 | 40 | public static List findSemanticdbFiles(ScipSemanticdbOptions options) throws IOException { 41 | SemanticdbWalker walker = new SemanticdbWalker(options); 42 | PathMatcher jarPattern = FileSystems.getDefault().getPathMatcher("glob:**.jar"); 43 | for (Path root : options.targetroots) { 44 | if (jarPattern.matches(root)) { 45 | walker.result.add(root); 46 | } else { 47 | Files.walkFileTree(root, walker); 48 | } 49 | } 50 | return walker.result; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SignatureFormatterException.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import com.sourcegraph.semanticdb_javac.Semanticdb; 4 | 5 | public class SignatureFormatterException extends RuntimeException { 6 | public SignatureFormatterException( 7 | Semanticdb.SymbolInformation symbolInformation, Throwable cause) { 8 | super( 9 | String.format( 10 | "failed to format symbol '%s'\n%s", symbolInformation.getSymbol(), symbolInformation), 11 | cause); 12 | } 13 | 14 | @Override 15 | public synchronized Throwable fillInStackTrace() { 16 | // This exception doesn't have a relevant stack trace. The cause exception 17 | // already points to the culprit filename and line number. 18 | return this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolOccurrences.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import com.sourcegraph.semanticdb_javac.Semanticdb; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class SymbolOccurrences { 9 | public List occurrences = new ArrayList<>(); 10 | 11 | public void addSyntheticDefinition(String sym) { 12 | occurrences.add( 13 | Semanticdb.SymbolOccurrence.newBuilder() 14 | .setSymbol(sym) 15 | .setRole(Semanticdb.SymbolOccurrence.Role.SYNTHETIC_DEFINITION) 16 | .build()); 17 | } 18 | 19 | public void addDefinition(String sym) { 20 | occurrences.add( 21 | Semanticdb.SymbolOccurrence.newBuilder() 22 | .setSymbol(sym) 23 | .setRole(Semanticdb.SymbolOccurrence.Role.DEFINITION) 24 | .build()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/SymbolRelationship.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | public class SymbolRelationship { 4 | public final String from; 5 | public final String to; 6 | 7 | public SymbolRelationship(String from, String to) { 8 | this.from = from; 9 | this.to = to; 10 | } 11 | 12 | public String getFrom() { 13 | return from; 14 | } 15 | 16 | public String getTo() { 17 | return to; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/java/com/sourcegraph/scip_semanticdb/Symtab.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.scip_semanticdb; 2 | 3 | import com.sourcegraph.semanticdb_javac.Semanticdb; 4 | 5 | import java.util.HashMap; 6 | 7 | public class Symtab { 8 | public final HashMap symbols = new HashMap<>(); 9 | 10 | public Symtab(Semanticdb.TextDocument document) { 11 | for (Semanticdb.SymbolInformation symbolInformation : document.getSymbolsList()) { 12 | symbols.put(symbolInformation.getSymbol(), symbolInformation); 13 | } 14 | } 15 | 16 | public Symtab withHardlinks(Semanticdb.Scope scope) { 17 | Symtab hardlinkSymtab = new Symtab(Semanticdb.TextDocument.getDefaultInstance()); 18 | hardlinkSymtab.symbols.putAll(this.symbols); 19 | for (int i = 0; i < scope.getHardlinksCount(); i++) { 20 | Semanticdb.SymbolInformation info = scope.getHardlinks(i); 21 | hardlinkSymtab.symbols.put(info.getSymbol(), info); 22 | } 23 | return hardlinkSymtab; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /scip-semanticdb/src/main/protobuf/lsif.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option java_multiple_files = true; 4 | 5 | package com.sourcegraph.lsif_protocol; 6 | 7 | message LsifObject { 8 | int32 id = 1; 9 | string type = 2; 10 | string label = 3; 11 | string version = 4; 12 | string projectRoot = 5; 13 | string positionEncoding = 6; 14 | LsifToolInfo toolInfo = 7; 15 | string kind = 8; 16 | string uri = 9; 17 | string language = 10; 18 | int32 outV = 12; 19 | int32 inV = 13; 20 | repeated int32 inVs = 14; 21 | int32 document = 15; 22 | LsifHover result = 16; 23 | string scheme = 17; 24 | string identifier = 18; 25 | LsifPosition start = 19; 26 | LsifPosition end = 20; 27 | string name = 21; 28 | string manager = 22; 29 | string property = 23; 30 | } 31 | 32 | message LsifToolInfo { 33 | string name = 1; 34 | string version = 2; 35 | repeated string args = 3; 36 | } 37 | 38 | message LsifPosition { 39 | int32 line = 1; 40 | int32 character = 2; 41 | } 42 | 43 | message LsifHover { 44 | Content contents = 1; 45 | message Content { 46 | string kind = 1; // not MarkupKind because must be lowercase 47 | string value = 2; 48 | } 49 | } 50 | 51 | enum MarkupKind { 52 | PLAINTEXT = 0; 53 | MARKDOWN = 1; 54 | } 55 | 56 | 57 | -------------------------------------------------------------------------------- /semanticdb-java/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_java//java:defs.bzl", "java_library", "java_proto_library") 2 | load("@rules_proto//proto:defs.bzl", "proto_library") 3 | 4 | package( 5 | default_visibility = ["//visibility:public"], 6 | ) 7 | 8 | java_proto_library( 9 | name = "semanticdb_java_proto", 10 | deps = [":semanticdb_proto"], 11 | ) 12 | 13 | proto_library( 14 | name = "semanticdb_proto", 15 | srcs = glob(["src/main/protobuf/*.proto"]), 16 | ) 17 | 18 | java_library( 19 | name = "semanticdb-java", 20 | srcs = glob(["src/main/java/**/*.java"]), 21 | deps = [ 22 | "//semanticdb-java/src/main/protobuf:semanticdb_java_proto", 23 | ], 24 | ) 25 | -------------------------------------------------------------------------------- /semanticdb-java/src/main/protobuf/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_java//java:defs.bzl", "java_proto_library") 2 | load("@rules_proto//proto:defs.bzl", "proto_library") 3 | 4 | package( 5 | default_visibility = ["//visibility:public"], 6 | ) 7 | 8 | java_proto_library( 9 | name = "semanticdb_java_proto", 10 | deps = [":semanticdb_proto"], 11 | ) 12 | 13 | proto_library( 14 | name = "semanticdb_proto", 15 | srcs = ["semanticdb.proto"] 16 | ) 17 | -------------------------------------------------------------------------------- /semanticdb-javac/BUILD: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//rules:common_settings.bzl", "string_flag") 2 | load("@rules_java//java:defs.bzl", "java_import", "java_library", "java_plugin") 3 | 4 | package( 5 | default_visibility = ["//visibility:public"], 6 | ) 7 | 8 | config_setting( 9 | name = "is_enabled", 10 | flag_values = {":enabled": "true"}, 11 | ) 12 | 13 | string_flag( 14 | name = "enabled", 15 | values = ["true", "false"], 16 | build_setting_default = "false", 17 | ) 18 | 19 | java_import( 20 | name = "javac-import", 21 | jars = ["@bazel_tools//third_party/java/jdk/langtools:javac_jar"], 22 | ) 23 | 24 | java_plugin( 25 | name = "plugin", 26 | deps = [ 27 | ":semanticdb-javac", 28 | ], 29 | ) 30 | 31 | 32 | java_library( 33 | name = "semanticdb-javac", 34 | srcs = glob(["src/main/java/**/*.java"]), 35 | resources = ["src/main/resources/META-INF/services/com.sun.source.util.Plugin"], 36 | deps = [ 37 | "//semanticdb-java/src/main/protobuf:semanticdb_java_proto", 38 | "//semanticdb-java", 39 | ":javac-import", 40 | ], 41 | ) 42 | -------------------------------------------------------------------------------- /semanticdb-javac/defs.bzl: -------------------------------------------------------------------------------- 1 | """Java rules that automatically register the SemanticDB compiler plugin based on the presence of a string flag.""" 2 | 3 | load("@rules_java//java:defs.bzl", native_java_binary = "java_binary", native_java_library = "java_library") 4 | 5 | def java_library(javacopts = [], plugins = [], **kwargs): 6 | native_java_library( 7 | javacopts = _actual_javacopts(javacopts), 8 | plugins = _actual_plugins(plugins), 9 | **kwargs 10 | ) 11 | 12 | def java_binary(javacopts = [], plugins = [], **kwargs): 13 | native_java_binary( 14 | javacopts = _actual_javacopts(javacopts), 15 | plugins = _actual_plugins(plugins), 16 | **kwargs 17 | ) 18 | 19 | def _actual_javacopts(javacopts): 20 | return select({ 21 | "@scip_java//semanticdb-javac:is_enabled": ["'-Xplugin:semanticdb -build-tool:bazel'"] + javacopts, 22 | "//conditions:default": javacopts, 23 | }) 24 | 25 | def _actual_plugins(plugins): 26 | return select({ 27 | "@scip_java//semanticdb-javac:is_enabled": ["@scip_java//semanticdb-javac:plugin"] + plugins, 28 | "//conditions:default": plugins, 29 | }) 30 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/CompilationUnitException.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | public class CompilationUnitException extends Throwable { 4 | public CompilationUnitException(String compilationUnit, Throwable cause) { 5 | super(compilationUnit, cause); 6 | } 7 | 8 | @Override 9 | public Throwable fillInStackTrace() { 10 | return this; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/Debugging.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | /** Utility methods for debugging purposes. */ 4 | public final class Debugging { 5 | public static void pprint(Object any) { 6 | StackTraceElement trace = new Exception().getStackTrace()[1]; 7 | if (any instanceof String) { 8 | any = String.format("\"%s\"", any); 9 | } 10 | System.out.printf("%s:%s %s%n", trace.getFileName(), trace.getLineNumber(), any); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/InjectSemanticdbOptions.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | import java.io.IOException; 4 | import java.io.OutputStream; 5 | import java.io.PrintStream; 6 | import java.nio.file.Files; 7 | import java.nio.file.Path; 8 | import java.nio.file.Paths; 9 | import java.util.List; 10 | 11 | public class InjectSemanticdbOptions { 12 | 13 | /** 14 | * Updates a list of Java compiler arguments to include -Xplugin:semanticdb. 15 | * 16 | *

This main method should be used by a `javac` wrapper script like this: 17 | * 18 | *

19 |    *     NEW_OPTIONS_PATH=$(mktemp)
20 |    *     java -cp semanticdb.jar \
21 |    *         -Dsemanticdb.output=NEW_OPTIONS_PATH \
22 |    *         com.sourcegraph.semanticdb_javac.InjectSemanticdbOptions $@
23 |    *     javac @$NEW_OPTIONS_PATH
24 |    * 
25 | * 26 | *

Requires the following system properties: 27 | * 28 | *

36 | * 37 | * @param args the Java compiler arguments to update. 38 | */ 39 | public static void main(String[] args) { 40 | try { 41 | runMain(args); 42 | } catch (IOException e) { 43 | if (!SemanticdbOptionBuilder.ERRORPATH.isEmpty()) { 44 | try { 45 | Path path = Paths.get(SemanticdbOptionBuilder.ERRORPATH); 46 | Files.createDirectories(path.getParent()); 47 | try (OutputStream out = Files.newOutputStream(path)) { 48 | e.printStackTrace(new PrintStream(out)); 49 | } 50 | } catch (Exception ignored) { 51 | } 52 | } 53 | } 54 | } 55 | 56 | public static void runMain(String[] args) throws IOException { 57 | SemanticdbOptionBuilder newArgs = new SemanticdbOptionBuilder(); 58 | for (String arg : args) { 59 | if (arg.startsWith("@")) { 60 | String filepath = arg.substring(1); 61 | Path path = Paths.get(filepath); 62 | if (Files.isRegularFile(path)) { 63 | List lines = Files.readAllLines(path); 64 | for (String line : lines) { 65 | newArgs.processArgument(line); 66 | } 67 | } 68 | } else { 69 | newArgs.processArgument(arg); 70 | } 71 | } 72 | newArgs.write(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/LocalSymbolsCache.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | import javax.lang.model.element.Element; 4 | 5 | import java.util.IdentityHashMap; 6 | 7 | /** Cache of SemanticDB symbols that are local to a single file. */ 8 | public final class LocalSymbolsCache { 9 | 10 | private final IdentityHashMap symbols = new IdentityHashMap<>(); 11 | private int localsCounter = -1; 12 | 13 | public String get(Element sym) { 14 | return symbols.get(sym); 15 | } 16 | 17 | public String put(Element sym) { 18 | localsCounter++; 19 | String result = SemanticdbSymbols.local(localsCounter); 20 | symbols.put(sym, result); 21 | return result; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/MD5.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | import java.nio.CharBuffer; 4 | import java.nio.charset.StandardCharsets; 5 | import java.security.MessageDigest; 6 | import java.security.NoSuchAlgorithmException; 7 | 8 | /** Utility to compute MD5 checksums of strings. */ 9 | public final class MD5 { 10 | private static final char[] HEX_ARRAY; 11 | 12 | static { 13 | HEX_ARRAY = "0123456789ABCDEF".toCharArray(); 14 | } 15 | 16 | private static String bytesToHex(byte[] bytes) { 17 | char[] hexChars = new char[bytes.length * 2]; 18 | int j = 0; 19 | while (j < bytes.length) { 20 | int v = bytes[j] & 0xFF; 21 | hexChars[j * 2] = HEX_ARRAY[v >>> 4]; 22 | hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; 23 | j += 1; 24 | } 25 | return new String(hexChars); 26 | } 27 | 28 | public static String digest(CharSequence chars) throws NoSuchAlgorithmException { 29 | MessageDigest md5 = MessageDigest.getInstance("MD5"); 30 | return bytesToHex(md5.digest(chars.toString().getBytes())); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/NoRelativePathMode.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | import java.util.Arrays; 4 | import java.util.stream.Collectors; 5 | 6 | /** 7 | * Configuration options to determine how semanticdb-javac should handle files that have no good 8 | * relative paths. 9 | * 10 | *

When indexing a file at an absolute path /project/src/main/example/Foo.java, SemanticDB needs 11 | * to know the "sourceroot" path /project in order to relativize the path of the source file into 12 | * src/main/example/Foo.java. This configuration option determines what the compiler plugin should 13 | * do when it's not able to find a good relative path. 14 | */ 15 | public enum NoRelativePathMode { 16 | 17 | /** 18 | * Come up with a unique relative path for the SemanticDB path with no guarantee that this path 19 | * corresponds to the original path of the generated source file. 20 | */ 21 | INDEX_ANYWAY, 22 | 23 | /** Silently ignore the file, don't index it. */ 24 | SKIP, 25 | 26 | /** Report an error message and fail the compilation. */ 27 | ERROR, 28 | 29 | /** Ignore the file, but print a message explaining it's ignored. */ 30 | WARNING; 31 | 32 | public static String validStringValuesWithoutError() { 33 | return Arrays.stream(NoRelativePathMode.values()) 34 | .filter(mode -> !mode.equals(ERROR)) 35 | .map(NoRelativePathMode::toString) 36 | .collect(Collectors.joining(", ")); 37 | } 38 | 39 | public static String validStringValues() { 40 | return Arrays.stream(NoRelativePathMode.values()) 41 | .map(NoRelativePathMode::toString) 42 | .collect(Collectors.joining(", ")); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/PrintJavaVersion.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | public class PrintJavaVersion { 4 | public static void main(String[] args) { 5 | System.out.print(System.getProperty("java.version")); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbPlugin.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | import com.sun.source.util.Plugin; 4 | import com.sun.source.util.JavacTask; 5 | import com.sun.source.util.Trees; 6 | 7 | /** Entrypoint of the semanticdb-javac compiler plugin. */ 8 | public class SemanticdbPlugin implements Plugin { 9 | 10 | public static String stubClassName = "META-INF-semanticdb-stub"; 11 | 12 | @Override 13 | public String getName() { 14 | return "semanticdb"; 15 | } 16 | 17 | @Override 18 | public void init(JavacTask task, String... args) { 19 | Trees trees = Trees.instance(task); 20 | SemanticdbReporter reporter = new SemanticdbReporter(trees); 21 | SemanticdbJavacOptions options = SemanticdbJavacOptions.parse(args, task); 22 | GlobalSymbolsCache globals = new GlobalSymbolsCache(options); 23 | task.addTaskListener(new SemanticdbTaskListener(options, task, trees, globals, reporter)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/SemanticdbReporter.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | import com.sun.source.tree.CompilationUnitTree; 4 | import com.sun.source.tree.Tree; 5 | import com.sun.source.util.Trees; 6 | import com.sun.source.util.TaskEvent; 7 | 8 | import javax.tools.Diagnostic; 9 | import java.io.ByteArrayOutputStream; 10 | import java.io.PrintWriter; 11 | 12 | /** 13 | * Utilities to report error messages. 14 | * 15 | *

NOTE(olafur): this class exists because I couldn't find compiler APIs to report diagnostics. 16 | * This class can be removed if the Java compiler has APIs to report info/warning/error messages. 17 | */ 18 | public class SemanticdbReporter { 19 | private final Trees trees; 20 | 21 | public SemanticdbReporter(Trees trees) { 22 | this.trees = trees; 23 | } 24 | 25 | public void exception(Throwable e, Tree tree, CompilationUnitTree root) { 26 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 27 | PrintWriter writer = new PrintWriter(baos); 28 | e.printStackTrace(writer); 29 | writer.println( 30 | "Please report a bug to https://github.com/sourcegraph/semanticdb-java with the stack trace above."); 31 | trees.printMessage(Diagnostic.Kind.ERROR, baos.toString(), tree, root); 32 | } 33 | 34 | public void exception(Throwable e, TaskEvent task) { 35 | this.exception(e, task.getCompilationUnit(), task.getCompilationUnit()); 36 | } 37 | 38 | public void info(String message, TaskEvent e) { 39 | trees.printMessage( 40 | Diagnostic.Kind.NOTE, 41 | "semanticdb-javac: " + message, 42 | e.getCompilationUnit(), 43 | e.getCompilationUnit()); 44 | } 45 | 46 | public void error(String message, TaskEvent e) { 47 | trees.printMessage( 48 | Diagnostic.Kind.ERROR, 49 | "semanticdb-javac: " + message, 50 | e.getCompilationUnit(), 51 | e.getCompilationUnit()); 52 | } 53 | 54 | public void error(String message, Tree tree, CompilationUnitTree root) { 55 | // NOTE(olafur): ideally, this message should be reported as a compiler 56 | // diagnostic, but I dind't 57 | // find 58 | // the reporter API so the message goes to stderr instead for now. 59 | trees.printMessage( 60 | Diagnostic.Kind.ERROR, String.format("semanticdb-javac: %s", message), tree, root); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/TargetPaths.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | import java.nio.file.Path; 4 | 5 | public class TargetPaths { 6 | public Path classes; 7 | public Path sources; 8 | 9 | public TargetPaths(Path classesDir, Path sourcesDir) { 10 | classes = classesDir; 11 | sources = sourcesDir; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/java/com/sourcegraph/semanticdb_javac/UriScheme.java: -------------------------------------------------------------------------------- 1 | package com.sourcegraph.semanticdb_javac; 2 | 3 | public enum UriScheme { 4 | DEFAULT, 5 | /** @deprecated Use ZINC instead */ 6 | @Deprecated 7 | SBT, 8 | BAZEL, 9 | ZINC 10 | } 11 | -------------------------------------------------------------------------------- /semanticdb-javac/src/main/resources/META-INF/services/com.sun.source.util.Plugin: -------------------------------------------------------------------------------- 1 | com.sourcegraph.semanticdb_javac.SemanticdbPlugin -------------------------------------------------------------------------------- /tests/benchmarks/src/main/scala/benchmarks/ScipSemanticdbBench.scala: -------------------------------------------------------------------------------- 1 | package benchmarks 2 | 3 | import java.nio.file.Files 4 | import java.nio.file.Path 5 | import java.util.concurrent.TimeUnit 6 | 7 | import com.sourcegraph.io.DeleteVisitor 8 | import com.sourcegraph.scip_java.Dependencies 9 | import com.sourcegraph.scip_java.ScipJava 10 | import org.openjdk.jmh.annotations._ 11 | import tests.TestCompiler 12 | 13 | @State(Scope.Benchmark) 14 | class ScipSemanticdbBench { 15 | 16 | var targetroot: Path = _ 17 | var deps: Dependencies = _ 18 | 19 | @Setup 20 | def setup(): Unit = { 21 | targetroot = Files.createTempDirectory("scip-java") 22 | deps = Dependencies 23 | .resolveDependencies(List("com.google.guava:guava:30.1-jre")) 24 | val compiler = 25 | new TestCompiler( 26 | deps.classpathSyntax, 27 | javacOptions = Nil, 28 | scalacOptions = Nil, 29 | targetroot 30 | ) 31 | CompileBench.foreachSource(deps) { inputs => 32 | compiler.compileSemanticdb(inputs).byteCode.length 33 | } 34 | } 35 | 36 | @TearDown 37 | def teardown(): Unit = { 38 | Files.walkFileTree(targetroot, new DeleteVisitor()) 39 | } 40 | 41 | @Benchmark 42 | @BenchmarkMode(Array(Mode.SingleShotTime)) 43 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 44 | def jsonParallel(): Unit = run("index.scip", parallel = true) 45 | 46 | @Benchmark 47 | @BenchmarkMode(Array(Mode.SingleShotTime)) 48 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 49 | def json(): Unit = run("index.scip", parallel = false) 50 | 51 | private def run(filename: String, parallel: Boolean): Unit = { 52 | val output = Files.createTempFile("scip-java", filename) 53 | val parallelFlag = 54 | if (parallel) 55 | "--parallel" 56 | else 57 | "--no-parallel" 58 | val exit = ScipJava 59 | .app 60 | .run( 61 | List( 62 | "index-semanticdb", 63 | s"--output=$output", 64 | parallelFlag, 65 | targetroot.toString 66 | ) 67 | ) 68 | 69 | require(exit == 0, exit) 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /tests/buildTools/src/main/scala/tests/GradleDefaultJvmLanguageCompileSpec.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.io.File 4 | import java.util 5 | 6 | import scala.jdk.CollectionConverters._ 7 | 8 | class GradleDefaultJvmLanguageCompileSpec(base: List[String]) { 9 | def getCompileClasspath: util.List[File] = { 10 | base.map(new File(_)).asJava 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/buildTools/src/main/scala/tests/GradleJavaCompilerArgumentsBuilder.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import scala.jdk.CollectionConverters._ 4 | 5 | class GradleJavaCompilerArgumentsBuilder(base: List[String]) { 6 | def build(): java.util.List[String] = base.asJava 7 | } 8 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/AutoBuildToolSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | class AutoBuildToolSuite extends BaseBuildToolSuite { 4 | checkErrorOutput( 5 | "no-tools-found", 6 | List("index", "--build-tool", "auto"), 7 | expectedOutput = 8 | """error: Build tool mode set to `auto`, but no supported build tools were detected""", 9 | workingDirectoryLayout = "" 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/GradleBuildToolSuiteBase.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.nio.file.Files 4 | import java.nio.file.StandardOpenOption 5 | 6 | import munit.TestOptions 7 | 8 | abstract class GradleBuildToolSuiteBase(gradle: Tool.Gradle) 9 | extends BaseBuildToolSuite { 10 | 11 | def gradleVersion(version: String): List[String] = { 12 | createEmptyBuildScript() 13 | List("gradle", "wrapper", "--gradle-version", version) 14 | } 15 | 16 | def createEmptyBuildScript(): Unit = { 17 | val script = workingDirectory.resolve("build.gradle") 18 | Files.createDirectories(script.getParent) 19 | Files.write( 20 | script, 21 | Array.emptyByteArray, 22 | StandardOpenOption.TRUNCATE_EXISTING, 23 | StandardOpenOption.CREATE 24 | ) 25 | } 26 | 27 | def checkGradleBuild( 28 | title: TestOptions, 29 | setup: String, 30 | expectedSemanticdbFiles: Int = 0, 31 | expectedPackages: String = "", 32 | extraArguments: List[String] = Nil, 33 | gradleVersions: List[Tool.Gradle] = Nil, 34 | tools: List[Tool] = Nil 35 | ) = { 36 | if (gradleVersions.contains(gradle)) { 37 | val testName = title.withName(title.name + s"-${gradle.name}") 38 | 39 | checkBuild( 40 | testName, 41 | setup, 42 | expectedSemanticdbFiles = expectedSemanticdbFiles, 43 | expectedPackages = expectedPackages, 44 | initCommand = gradleVersion(gradle.version), 45 | extraArguments = extraArguments, 46 | tools = tools :+ gradle 47 | ) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/GradleDefaultJvmLanguageCompileSpecSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import scala.jdk.CollectionConverters._ 4 | 5 | import munit.FunSuite 6 | import munit.TestOptions 7 | 8 | class GradleDefaultJvmLanguageCompileSpecSuite extends FunSuite { 9 | val pluginpath = System.getProperty("semanticdb.pluginpath") 10 | def check( 11 | options: TestOptions, 12 | original: List[String], 13 | expected: List[String] 14 | ): Unit = { 15 | test(options) { 16 | val obtained = 17 | new GradleDefaultJvmLanguageCompileSpec(original) 18 | .getCompileClasspath 19 | .asScala 20 | .map(_.toString) 21 | .toList 22 | assertEquals(obtained, expected) 23 | } 24 | } 25 | 26 | check("empty", List(), List(pluginpath)) 27 | check("non-empty", List("foo"), List("foo", pluginpath)) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/GradleJavaCompilerArgumentsBuilderSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.io.File 4 | 5 | import scala.jdk.CollectionConverters._ 6 | 7 | import munit.FunSuite 8 | import munit.TestOptions 9 | 10 | class GradleJavaCompilerArgumentsBuilderSuite extends FunSuite { 11 | val targetroot = System.getProperty("semanticdb.targetroot") 12 | val sourceroot = System.getProperty("semanticdb.sourceroot") 13 | val pluginpath = System.getProperty("semanticdb.pluginpath") 14 | val Xplugin = 15 | s"-Xplugin:semanticdb -sourceroot:$sourceroot -targetroot:$targetroot" 16 | def check( 17 | options: TestOptions, 18 | original: List[String], 19 | expected: List[String] 20 | ): Unit = { 21 | test(options) { 22 | val obtained = 23 | new GradleJavaCompilerArgumentsBuilder(original).build().asScala.toList 24 | assertEquals(obtained, expected) 25 | } 26 | } 27 | 28 | check( 29 | "basic", 30 | List("-Arandom"), 31 | List("-Arandom", "-classpath", pluginpath, Xplugin) 32 | ) 33 | 34 | check( 35 | "only-classpath", 36 | List("-classpath", "a.jar"), 37 | List( 38 | "-classpath", 39 | List(pluginpath, "a.jar").mkString(File.pathSeparator), 40 | Xplugin 41 | ) 42 | ) 43 | 44 | check( 45 | "only-processorpath", 46 | List("-processorpath", "a.jar"), 47 | List( 48 | "-processorpath", 49 | List(pluginpath, "a.jar").mkString(File.pathSeparator), 50 | Xplugin 51 | ) 52 | ) 53 | 54 | check( 55 | "classpath-and-processorpath", 56 | List("-classpath", "a.jar", "-processorpath", "b.jar"), 57 | List( 58 | "-classpath", 59 | List(pluginpath, "a.jar").mkString(File.pathSeparator), 60 | "-processorpath", 61 | List(pluginpath, "b.jar").mkString(File.pathSeparator), 62 | Xplugin 63 | ) 64 | ) 65 | 66 | } 67 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/MavenBuildToolSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import scala.meta.internal.io.InputStreamIO 4 | 5 | class MavenBuildToolSuite extends BaseBuildToolSuite { 6 | override def tags = List(SkipWindows) 7 | 8 | lazy val pomXml = 9 | new String( 10 | InputStreamIO 11 | .readBytes(this.getClass.getResourceAsStream("/example-maven-pom.xml")) 12 | ) 13 | 14 | checkBuild( 15 | options = "basic", 16 | original = 17 | s""" 18 | |/pom.xml 19 | |$pomXml 20 | |/src/main/java/com/Example.java 21 | |package com; 22 | |public class Example {} 23 | |/src/test/java/com/ExampleSuite.java 24 | |package com; 25 | |public class ExampleSuite {} 26 | |""".stripMargin, 27 | expectedSemanticdbFiles = 2, 28 | expectedPackages = 29 | """|maven:com.sourcegraph:example:1.0-SNAPSHOT 30 | |maven:junit:junit:4.11 31 | |maven:org.hamcrest:hamcrest-core:1.3 32 | |""".stripMargin 33 | ) 34 | 35 | checkBuild( 36 | "build-command", 37 | s"""|/pom.xml 38 | |$pomXml 39 | |/src/main/java/com/Example.java 40 | |package com; 41 | |public class Example {} 42 | |/src/test/java/com/ExampleSuite.java 43 | |package com; 44 | |public class ExampleSuite {} 45 | |""".stripMargin, 46 | 1, 47 | extraArguments = List("--", "compile") 48 | ) 49 | 50 | } 51 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/MissingBuildToolSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | class MissingBuildToolSuite extends BaseBuildToolSuite { 4 | 5 | checkErrorOutput( 6 | "basic", 7 | List("index"), 8 | expectedOutput = 9 | s"""|error: No build tool detected in workspace '${java.io.File.separator}workingDirectory'. At the moment, the only supported build tools are: Maven, Gradle, sbt, mill. 10 | |""".stripMargin, 11 | workingDirectoryLayout = "" 12 | ) 13 | 14 | checkErrorOutput( 15 | "ambiguous", 16 | List("index"), 17 | expectedOutput = 18 | """|error: Multiple build tools detected: Maven, Gradle. To fix this problem, use the '--build-tool=BUILD_TOOL_NAME' flag to specify which build tool to run. 19 | |""".stripMargin, 20 | workingDirectoryLayout = 21 | """|/pom.xml 22 | | 23 | |/build.gradle 24 | |def foo= 42 25 | |""".stripMargin 26 | ) 27 | 28 | checkErrorOutput( 29 | "no-matching-explicit", 30 | List("index", "--build-tool", "Gradle"), 31 | expectedOutput = 32 | """|error: Automatically detected the build tool(s) Maven but none of them match the explicitly provided flag '--build-tool=Gradle'. To fix this problem, run again with the --build-tool flag set to one of the detected build tools. 33 | |""".stripMargin, 34 | workingDirectoryLayout = 35 | """|/pom.xml 36 | | 37 | |""".stripMargin 38 | ) 39 | 40 | checkErrorOutput( 41 | "levenshtein", 42 | List("index", "--build-tool", "Mave"), 43 | expectedOutput = 44 | """|error: Automatically detected the build tool(s) Maven but none of them match the explicitly provided flag '--build-tool=Mave'. Did you mean --build-tool=Maven? 45 | |""".stripMargin, 46 | workingDirectoryLayout = 47 | """|/pom.xml 48 | | 49 | |""".stripMargin 50 | ) 51 | } 52 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/SbtBuildToolSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import tests.Tool.SBT15 4 | 5 | abstract class SbtBuildToolSuite(sbt: Tool.SBT) extends BaseBuildToolSuite { 6 | 7 | import Tool._ 8 | 9 | for { 10 | scala <- List(Scala211, Scala2_12_12, Scala2_13_8, Scala3) 11 | } yield { 12 | checkBuild( 13 | s"basic-${sbt.name}-${scala.name}", 14 | s"""|/build.sbt 15 | |scalaVersion := "${scala.version}" 16 | |libraryDependencies += "junit" % "junit" % "4.13.2" 17 | |/project/build.properties 18 | |sbt.version=${sbt.version} 19 | |/src/main/java/example/ExampleJava.java 20 | |package example; 21 | |import org.junit.Assert; 22 | |public class ExampleJava {} 23 | |/src/main/scala/example/ExampleScala.scala 24 | |package example 25 | |import org.junit.Assert 26 | |class ExampleScala() 27 | |/src/test/java/example/ExampleJavaSuite.java 28 | |package example; 29 | |public class ExampleJavaSuite {} 30 | |/src/test/scala/example/ExampleaSuite.scala 31 | |package example 32 | |class ExampleSuite() {} 33 | |""".stripMargin, 34 | expectedSemanticdbFiles = 4, 35 | targetRoot = Some("target"), 36 | tools = List(scala, sbt) 37 | ) 38 | } 39 | 40 | checkBuild( 41 | s"custom-sbt-command-${sbt.name}", 42 | s"""|/build.sbt 43 | |lazy val bla = project.in(file("bla")) 44 | |lazy val blaJS = project.in(file("bla-js")).enablePlugins(ScalaJSPlugin) 45 | |/project/plugins.sbt 46 | |addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.14.0") 47 | |/project/build.properties 48 | |sbt.version=${sbt.version} 49 | |/bla/src/main/scala/example/ExampleScala.scala 50 | |package example 51 | |class ExampleScala() 52 | |/bla-js/src/main/scala/example/ExampleScala.scala 53 | |package example 54 | |class ExampleScala!!!() // this file is intentionally broken 55 | |""".stripMargin, 56 | expectedSemanticdbFiles = 1, 57 | extraArguments = List("--", "bla/compile"), 58 | targetRoot = Some("bla/target"), 59 | tools = List(sbt) 60 | ) 61 | } 62 | 63 | import Tool._ 64 | 65 | class Sbt_15_BuildToolSuite extends SbtBuildToolSuite(SBT15) 66 | class Sbt_110_BuildToolSuite extends SbtBuildToolSuite(SBT110) 67 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/SkipWindows.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | object SkipWindows extends munit.Tag("SkipWindows") 4 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/Tool.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | case class JVMSupport(minJava: Int, maxJava: Option[Int] = None) { 4 | def supports(javaVersion: Int) = 5 | javaVersion >= minJava && 6 | (maxJava.isEmpty || maxJava.exists(javaVersion <= _)) 7 | } 8 | object JVMSupport { 9 | val noRestrictions = JVMSupport(8, None) 10 | def atMostJava(j: Int) = JVMSupport(8, Some(j)) 11 | def atLeastJava(j: Int) = JVMSupport(j, None) 12 | def javaBetween(min: Int, max: Int) = JVMSupport(min, Some(max)) 13 | 14 | } 15 | 16 | sealed abstract class Tool( 17 | val label: String, 18 | val version: String, 19 | val support: JVMSupport 20 | ) extends Product 21 | with Serializable { 22 | def name = s"$label-$version" 23 | } 24 | 25 | object Tool { 26 | import JVMSupport._ 27 | 28 | def minimumSupportedJdk(tools: Seq[Tool]): Int = 29 | tools.map(_.support.minJava).minOption.getOrElse(8) 30 | 31 | def maximumSupportedJdk(tools: Seq[Tool]): Option[Int] = 32 | tools.flatMap(_.support.maxJava).minOption 33 | 34 | // See https://docs.gradle.org/current/userguide/compatibility.html 35 | sealed abstract class Gradle(version: String, support: JVMSupport) 36 | extends Tool("gradle", version, support) 37 | case object Gradle8 extends Gradle("8.7", atMostJava(21)) 38 | case object Gradle7 extends Gradle("7.6.1", atMostJava(17)) 39 | case object Gradle6 extends Gradle("6.8.3", atMostJava(11)) 40 | case object Gradle5 extends Gradle("5.6.4", atMostJava(11)) 41 | case object Gradle3 extends Gradle("3.3", atMostJava(8)) 42 | case object Gradle2 extends Gradle("2.14.1", atMostJava(8)) 43 | 44 | sealed abstract class SBT(version: String, support: JVMSupport) 45 | extends Tool("sbt", version, support) 46 | // See https://docs.scala-lang.org/overviews/jdk-compatibility/overview.html#build-tool-compatibility-table 47 | case object SBT15 extends SBT("1.5.2", atMostJava(17)) 48 | case object SBT110 extends SBT("1.10.0", noRestrictions) 49 | 50 | sealed abstract class Scala(version: String, support: JVMSupport) 51 | extends Tool("scala", version, support) 52 | // See https://docs.scala-lang.org/overviews/jdk-compatibility/overview.html 53 | case object Scala213 extends Scala("2.13.13", noRestrictions) 54 | case object Scala212 extends Scala("2.12.19", noRestrictions) 55 | case object Scala2_12_12 extends Scala("2.12.12", atMostJava(11)) 56 | case object Scala2_13_8 extends Scala("2.13.8", atMostJava(17)) 57 | case object Scala211 extends Scala("2.11.9", atMostJava(11)) 58 | case object Scala3 extends Scala("3.3.3", noRestrictions) 59 | 60 | sealed abstract class Mill(version: String, support: JVMSupport) 61 | extends Tool("mill", version, support) 62 | // See https://docs.scala-lang.org/overviews/jdk-compatibility/overview.html#build-tool-compatibility-table 63 | case object Mill0_10 extends Mill("0.10.6", atMostJava(17)) 64 | case object Mill0_11 extends Mill("0.11.5", noRestrictions) 65 | 66 | } 67 | -------------------------------------------------------------------------------- /tests/buildTools/src/test/scala/tests/TracingServer.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.net.URI 4 | 5 | import scala.collection.mutable.ListBuffer 6 | import scala.jdk.CollectionConverters._ 7 | 8 | import com.sun.net.httpserver._ 9 | 10 | object TracingServer { 11 | case class SimpleHttpRequest(url: URI, simpleHeaders: Map[String, String]) 12 | 13 | case class RunningServer(address: URI, shutdown: () => Unit) 14 | 15 | private def runImpl[A](handler: MyHandler)(f: RunningServer => A) = { 16 | val server = HttpServer 17 | .create(new java.net.InetSocketAddress("localhost", 0), 0); 18 | val result = 19 | try { 20 | server.createContext("/", handler) 21 | server.setExecutor(null) // creates a default executor 22 | server.start() 23 | f( 24 | RunningServer( 25 | new URI( 26 | s"http://${server.getAddress().getHostName()}:${server.getAddress().getPort()}" 27 | ), 28 | () => server.stop(0) 29 | ) 30 | ) 31 | } finally { 32 | server.stop(0) 33 | } 34 | 35 | handler.tracedRequests -> result 36 | } 37 | 38 | def run[A](f: RunningServer => A): (List[SimpleHttpRequest], A) = { 39 | runImpl(new MyHandler(auth = None))(f) 40 | } 41 | def runWithAuth[A](username: String, password: String)( 42 | f: RunningServer => A 43 | ): (List[SimpleHttpRequest], A) = { 44 | val authenticator = 45 | new BasicAuthenticator("") { 46 | override def checkCredentials( 47 | _username: String, 48 | _password: String 49 | ): Boolean = username == _username && _password == password 50 | } 51 | 52 | runImpl(new MyHandler(auth = Some(authenticator)))(f) 53 | } 54 | 55 | private class MyHandler(auth: Option[Authenticator] = None) 56 | extends HttpHandler { 57 | 58 | val storage: ListBuffer[SimpleHttpRequest] = ListBuffer.empty 59 | 60 | override def handle(t: HttpExchange): Unit = { 61 | val headers = t 62 | .getRequestHeaders() 63 | .asScala 64 | .toMap 65 | .flatMap { case (k, v) => 66 | v.asScala.headOption.map(k -> _) 67 | } 68 | 69 | val url = t.getRequestURI() 70 | storage.synchronized { 71 | storage.addOne(SimpleHttpRequest(url, headers)) 72 | } 73 | 74 | auth.foreach { 75 | _.authenticate(t) match { 76 | case f: Authenticator.Failure => 77 | t.sendResponseHeaders(f.getResponseCode(), 0L) 78 | case r: Authenticator.Retry => 79 | t.sendResponseHeaders(r.getResponseCode(), 0L) 80 | case r: Authenticator.Success => 81 | t.sendResponseHeaders(404, 0L) 82 | } 83 | } 84 | 85 | t.close() 86 | } 87 | 88 | def tracedRequests = storage.result 89 | 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tests/gradle-example/.gitignore: -------------------------------------------------------------------------------- 1 | index.scip 2 | semanticdb-targetroot/ 3 | .classpath 4 | .project 5 | .settings 6 | .gradle 7 | eclipsebin 8 | 9 | bin 10 | gen 11 | build 12 | out 13 | lib 14 | generated 15 | 16 | target 17 | pom.xml.* 18 | release.properties 19 | local.properties 20 | 21 | .idea 22 | *.iml 23 | *.ipr 24 | *.iws 25 | classes 26 | 27 | obj 28 | 29 | .DS_Store 30 | 31 | # Special Mkdocs files 32 | docs/4.x 33 | docs/changelog.md 34 | docs/contributing.md 35 | docs/index.md 36 | -------------------------------------------------------------------------------- /tests/gradle-example/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | -------------------------------------------------------------------------------- /tests/gradle-example/src/main/java/example/Example.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | public class Example {} 4 | -------------------------------------------------------------------------------- /tests/gradle-example/src/test/java/example/ExampleTest.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | public class ExampleTest {} 4 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/Issue396.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | case class Issue396(a: Int) 4 | object Issue396App { 5 | println(Issue396) 6 | Issue396.apply(a = 42).copy(a = 41) 7 | Issue396.apply(a = 42).productElement(0) 8 | Issue396.apply(a = 42).productElementName(0) 9 | } 10 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/Issue397.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | class Issue397 { 4 | var blah = Set("abc") 5 | blah = Set.empty[String] 6 | } 7 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/Issue403.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | case class Issue403(value: String) 4 | 5 | object Issue403App { 6 | def instantiations(): Unit = { 7 | println(Issue403("a").value) 8 | println(Issue403.apply("a").value) 9 | println(new Issue403("a").value) 10 | 11 | Issue403("a") match { 12 | case Issue403(value) => 13 | println(value) 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/Issue412.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | class Issue412 { 4 | val a: Int = 5 5 | val b: Long = a 6 | 7 | def a(b: Long): Unit = { 8 | println(b) 9 | } 10 | a(a) 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/Issue413.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | trait Issue413 { 4 | val b: Int 5 | val c: Int 6 | } 7 | object Issue413 { 8 | def main(): Unit = { 9 | val a = new Issue413Subclass() 10 | val b: Issue413 = a 11 | println(a.b + b.b) 12 | } 13 | } 14 | 15 | class Issue413Subclass extends Issue413 { 16 | override val b = 10 17 | override val c = 10 18 | } 19 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/Issue414.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | object Issue414 { 4 | trait A { 5 | def b(): Unit 6 | } 7 | val a1 = 8 | new A { 9 | override def b(): Unit = { 10 | print("Hello") 11 | } 12 | } 13 | val a2: A = a1 14 | println(a1.b()) 15 | println(a2.b()) 16 | } 17 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/Issue414Reference.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | object Issue414Reference { 4 | println(Issue414.a1.b()) 5 | println(Issue414.a2.b()) 6 | } 7 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/MinimizedScalaMain.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | // format: off 4 | object MinimizedScalaMain { 5 | def main(args: Array[String]): Unit = { 6 | TypeVariables.app(new TypeVariables.CT()); 7 | System.out.println( 8 | Methods.app(42, "42") + 9 | Enums.app() + 10 | Docstrings.app() + 11 | InnerClasses.app() + 12 | ForComprehensions.app(42) + 13 | AnonymousClasses.app(42) + 14 | Primitives.app() + 15 | new ParameterizedTypes[Integer, String]() 16 | .app(42, "42") + 17 | RawTypes.x.toString + 18 | ClassOf.app() + 19 | SubClasses.app() + 20 | Fields.app() 21 | ) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/MinimizedScalaSignatures.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | // format: off 4 | 5 | 6 | case class MinimizedCaseClass(value: String) { 7 | def this() = this(value = "value") 8 | } 9 | object MinimizedCaseClass { 10 | def main(): Unit = { 11 | println(MinimizedCaseClass.apply(value = "value1").copy(value = "value2").value) 12 | } 13 | } 14 | 15 | trait MinimizedTrait[T] extends AutoCloseable { 16 | def add(e: T): T 17 | final def +(e: T): T = add(e) 18 | } 19 | 20 | class MinimizedScalaSignatures extends AutoCloseable with java.io.Serializable { 21 | def close(): Unit = () 22 | } 23 | 24 | object MinimizedScalaSignatures extends MinimizedScalaSignatures with Comparable[Int] { 25 | @inline def annotation(x: Int): Int = x + 1 26 | @deprecated("2020-07-27") def annotationMessage(x: Int): Int = x + 1 27 | def compareTo(x: Int): Int = ??? 28 | def identity[T](e: T): T = e 29 | def tuple(): (Int, String) = null 30 | def function0(): () => String = null 31 | def function1(): Int => String = null 32 | def function2(): (Int, String) => Unit = null 33 | def typeParameter(): Map[Int, String] = null 34 | def termParameter(a: Int, b: String): String = null 35 | def singletonType(e: String): e.type = e 36 | def thisType(): this.type = this 37 | def constantInt(): 1 = 1 38 | def constantString(): "string" = "string" 39 | def constantBoolean(): true = true 40 | def constantFloat(): 1.2f = 1.2f 41 | def constantChar(): 'a' = 'a' 42 | def structuralType(): { val x: Int; def foo(a: Int): String } = null 43 | def byNameType(a: => Int): Unit = () 44 | def repeatedType(a: Int*): Unit = () 45 | 46 | type TypeAlias = Int 47 | type ParameterizedTypeAlias[A] = () => A 48 | type ParameterizedTypeAlias2[A, B] = A => B 49 | type TypeBound 50 | type TypeUpperBound <: String 51 | type TypeLowerBound >: CharSequence 52 | type TypeLowerUpperBound >: String <: CharSequence 53 | } 54 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/MinimizedScalaSynthetic.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | import scala.concurrent.ExecutionContext.Implicits.global 4 | import scala.concurrent.Future 5 | 6 | class MinimizedScalaSynthetic { 7 | def everything(): Unit = Future(1) 8 | def applyTree(): Unit = Future.apply[Int](1) 9 | def applyTree2(): Unit = List.apply[Int](1).sorted 10 | def selectTree(): Unit = Future[Int](1) 11 | def typeApplyTree(): Unit = Future.apply(1) 12 | def forComprehensions(): Unit = 13 | for { 14 | x <- Future(1) 15 | y <- Future.successful(1) 16 | if y < 2 17 | z <- Future.apply[Int](1) 18 | } yield x + y + z 19 | } 20 | -------------------------------------------------------------------------------- /tests/minimized-scala/src/main/scala/minimized/ReflectiveCall.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | 3 | import scala.language.reflectiveCalls 4 | 5 | class ReflectiveCall { 6 | // Reproduction for https://github.com/scalameta/scalameta/issues/2788 7 | val a = 8 | new { 9 | val b = 1 10 | } 11 | println(a.b) 12 | } 13 | -------------------------------------------------------------------------------- /tests/minimized/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_java//java:defs.bzl", "java_library") 2 | 3 | java_library( 4 | name = "minimized", 5 | srcs = glob(["src/main/java/minimized/*.java"]), 6 | deps = [ 7 | "@maven//:org_projectlombok_lombok", 8 | ], 9 | plugins = [ 10 | "//semanticdb-javac:plugin", 11 | ], 12 | javacopts = [ 13 | "'-Xplugin:semanticdb -build-tool:bazel'", 14 | ], 15 | ) 16 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/AbstractClasses.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public abstract class AbstractClasses { 4 | public String defaultImplementation() { 5 | return ""; 6 | } 7 | 8 | public abstract String abstractImplementation(); 9 | } 10 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/AnnotationParameters.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | @interface Bar { 4 | double value(); 5 | } 6 | 7 | @interface BarB { 8 | boolean value(); 9 | } 10 | 11 | @interface Nullable { 12 | String value() default ""; 13 | } 14 | 15 | 16 | @interface BarRef{ 17 | SuppressWarnings value(); 18 | } 19 | 20 | interface Foo { 21 | @Bar(-1d) 22 | double test(); 23 | 24 | @Bar(~5) 25 | @SuppressWarnings(value = "unchecked") 26 | double test2(); 27 | 28 | @BarB(!true) 29 | double test3(); 30 | 31 | @Nullable(("what")) 32 | Foo test4(); 33 | 34 | @Bar((double) -1) 35 | double testCast(); 36 | } 37 | 38 | interface TestRef { 39 | @BarRef(@SuppressWarnings(value = "unchecked")) 40 | abstract double testCase(); 41 | } 42 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/Annotations.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | import static java.lang.annotation.ElementType.*; 9 | 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(value = {CONSTRUCTOR, 13 | FIELD, 14 | LOCAL_VARIABLE, 15 | METHOD, 16 | PACKAGE, 17 | PARAMETER, 18 | TYPE} 19 | ) 20 | public @interface Annotations { 21 | 22 | String value() default ""; 23 | 24 | String format() default ""; 25 | } 26 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/AnnotationsOnParameterizedTypes.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.lang.reflect.InvocationHandler; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | import java.util.concurrent.ConcurrentMap; 7 | import java.util.function.Function; 8 | 9 | public interface AnnotationsOnParameterizedTypes { 10 | 11 | public static AnnotationsOnParameterizedTypes getInstance() { 12 | return new AnnotationsOnParameterizedTypesImpl(); 13 | } 14 | 15 | Function adapter(Class contract, Class wrappedClass); 16 | } 17 | 18 | 19 | class AnnotationsOnParameterizedTypesImpl implements AnnotationsOnParameterizedTypes { 20 | private ConcurrentMap, Constructor> proxyConstructors = new ConcurrentHashMap<>(); 21 | 22 | @Override 23 | public Function adapter(Class contract, Class wrappedClass) { 24 | 25 | Function constructor = getConstructor(contract); 26 | 27 | System.out.println(constructor); 28 | 29 | return null; 30 | } 31 | 32 | private Function getConstructor(Class contract) { 33 | @SuppressWarnings("unchecked") 34 | Constructor constructor = (Constructor) proxyConstructors.computeIfAbsent(contract, c -> { 35 | return null; 36 | }); 37 | 38 | System.out.println(constructor); 39 | 40 | return null; 41 | } 42 | } -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/AnonymousClasses.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.util.function.Function; 4 | 5 | @SuppressWarnings("ALL") 6 | public class AnonymousClasses { 7 | public static int app(int n) { 8 | Function fn = 9 | new Function() { 10 | @Override 11 | public Integer apply(Integer integer) { 12 | return integer + n; 13 | } 14 | }; 15 | 16 | return fn.apply(n); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/Arrays.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public class Arrays { 4 | public static String app() { 5 | int[] a = {1, 2, 3}; 6 | String[] b = {"1", "2", "3"}; 7 | int[][] c = {{1}, {2}, {3}}; 8 | String[][] d = {{"1"}, {"2"}, {"3"}}; 9 | return b[0] + a[0] + c[1][0] + d[1][0]; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/ClassOf.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public class ClassOf { 4 | public static String app() { 5 | return ClassOf.class.getName(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/Docstrings.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | /** Example class docstring. */ 4 | public class Docstrings { 5 | 6 | /** Example field docstring. */ 7 | public static int field = 42; 8 | 9 | /** 10 | * Example method docstring. 11 | * 12 | * @return 42. 13 | */ 14 | public static int method() { 15 | return 42; 16 | } 17 | 18 | /** 19 | * Example method parameter docstring. 20 | * 21 | * @param n The parameter. 22 | * @return The number + 42. 23 | */ 24 | public static int methodParameter(int n) { 25 | return n + 42; 26 | } 27 | 28 | public static String app() { 29 | return String.format("%s%s%s", field, method(), methodParameter(42)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/Enums.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.util.Arrays; 4 | import java.util.stream.Collectors; 5 | 6 | enum Enums { 7 | A("A", 420), 8 | B("B", 1), 9 | C("C", 5); 10 | public String value; 11 | 12 | Enums(String value, int a) { 13 | this.value = value; 14 | } 15 | 16 | public static String app() { 17 | String all = Arrays.stream(values()).map(e -> e.value).map(Enums::valueOf).collect(Collectors.toList()).toString(); 18 | return all + A.value + B.value + C.value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/Fields.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public class Fields { 4 | private final int privateField = 0; 5 | protected int protectedField = 0; 6 | public int publicField = 0; 7 | private static final int staticPrivateField = 0; 8 | protected static int staticProtectedFields = 0; 9 | public static int staticPublicField = 0; 10 | 11 | public class InnerFields { 12 | public int publicInnerField = publicField; 13 | } 14 | 15 | public static class InnerStaticFields { 16 | public int publicNonStaticInnerField = 0; 17 | public static int publicStaticInnerField = 0; 18 | } 19 | 20 | public static String app() { 21 | Fields fields = new Fields(); 22 | InnerFields innerFields = fields.new InnerFields(); 23 | InnerStaticFields innerStaticFields = new InnerStaticFields(); 24 | return String.valueOf(fields.privateField) 25 | + fields.protectedField 26 | + fields.publicField 27 | + staticPrivateField 28 | + staticProtectedFields 29 | + staticPublicField 30 | + innerFields.publicInnerField 31 | + InnerStaticFields.publicStaticInnerField 32 | + innerStaticFields.publicNonStaticInnerField; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/ForComprehensions.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | public class ForComprehensions { 7 | public static int app(int n) { 8 | List integers = Collections.singletonList(n); 9 | int result = 0; 10 | for (int i : integers) { 11 | result += i; 12 | } 13 | return result; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/InnerClasses.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public class InnerClasses { 4 | 5 | private final int exampleField; 6 | 7 | private static final String STRING = "asdf"; 8 | 9 | private static final int top = 5; 10 | private static final int bottom = 10; 11 | 12 | public InnerClasses(int exampleField) { 13 | this.exampleField = exampleField; 14 | } 15 | 16 | public enum InnerEnum { 17 | A, 18 | B, 19 | C 20 | } 21 | 22 | public interface InnerInterface { 23 | B apply(A a); 24 | } 25 | 26 | public @interface InnerAnnotation { 27 | int value(); 28 | } 29 | 30 | @SuppressWarnings(STRING + " ") 31 | @InnerAnnotation(top / bottom) 32 | public static class InnerStaticClass { 33 | 34 | public static void innerStaticMethod() {} 35 | } 36 | 37 | public class InnerClass implements InnerInterface { 38 | private final int field; 39 | 40 | public InnerClass(int field) { 41 | this.field = field; 42 | } 43 | 44 | public void innerMethod() { 45 | System.out.println(field + exampleField); 46 | } 47 | 48 | @Override 49 | public Integer apply(Integer integer) { 50 | return field * integer; 51 | } 52 | } 53 | 54 | private static B runInnerInterface(InnerInterface fn, A a) { 55 | return fn.apply(a); 56 | } 57 | 58 | public static void testEnum(InnerEnum magicEnum) { 59 | if (System.nanoTime() > System.currentTimeMillis()) { 60 | magicEnum = InnerEnum.B; 61 | } 62 | switch (magicEnum) { 63 | case B: 64 | System.out.println("b"); 65 | break; 66 | case A: 67 | System.out.println("a"); 68 | break; 69 | default: 70 | break; 71 | } 72 | if (magicEnum == InnerEnum.A) System.out.println("a"); 73 | else if (magicEnum == InnerEnum.C) System.out.println("b"); 74 | else System.out.println("c"); 75 | } 76 | 77 | public static void testAnon() { 78 | InnerInterface fn = 79 | new InnerInterface() { 80 | @Override 81 | public String apply(String s) { 82 | return s + "b"; 83 | } 84 | }; 85 | System.out.println(fn.apply("a")); 86 | } 87 | 88 | public static String app() { 89 | int a = 42; 90 | InnerStaticClass.innerStaticMethod(); 91 | InnerClasses innerClasses = new InnerClasses(a); 92 | InnerClass innerClass = innerClasses.new InnerClass(a); 93 | innerClass.innerMethod(); 94 | System.out.println(runInnerInterface(innerClass, a)); 95 | testEnum(InnerEnum.A); 96 | testAnon(); 97 | return ""; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/Interfaces.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public interface Interfaces { 4 | static void staticInterfaceMethod() {} 5 | 6 | String abstractInterfaceMethod(); 7 | 8 | default String defaultInterfaceMethod() { 9 | return "default"; 10 | } 11 | } 12 | 13 | interface BookService { 14 | void checkPages(); 15 | } 16 | 17 | interface MyService { 18 | BookService bookService(); 19 | 20 | default void example() { 21 | bookService().checkPages(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/LombokBuilder.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | @lombok.Builder 4 | class Hello { 5 | private String message; 6 | } 7 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/Methods.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public class Methods { 4 | private int overload(int value) { 5 | return value + 1; 6 | } 7 | 8 | private String overload(String value) { 9 | return value + "1"; 10 | } 11 | 12 | private static int staticOverload(int value) { 13 | return value + 1; 14 | } 15 | 16 | private static String staticOverload(String value) { 17 | return value + "1"; 18 | } 19 | 20 | public static String app(int n, String m) throws RuntimeException, IndexOutOfBoundsException { 21 | Methods methods = new Methods(); 22 | int a = staticOverload(n); 23 | String b = staticOverload(m); 24 | int c = methods.overload(n); 25 | String d = methods.overload(m); 26 | return b + a + c + d; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/MinimizedJavaMain.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | @Annotations(value = "value", format = "format") 4 | public class MinimizedJavaMain { 5 | public static void main(String[] args) { 6 | TypeVariables.app(new TypeVariables.CT()); 7 | System.out.println( 8 | Methods.app(42, "42") 9 | + Enums.app() 10 | + Docstrings.app() 11 | + InnerClasses.app() 12 | + ForComprehensions.app(42) 13 | + AnonymousClasses.app(42) 14 | + Primitives.app() 15 | + new ParameterizedTypes().app(42, "42") 16 | + RawTypes.x.toString() 17 | + ClassOf.app() 18 | + SubClasses.app() 19 | + Fields.app()); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/ParameterizedTypes.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.util.HashMap; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | public class ParameterizedTypes { 9 | public & Iterator> void iteratorable(List list) {} 10 | 11 | public String app(A a, B b) { 12 | return a.toString() + b; 13 | } 14 | 15 | public Map doStuff() { return null; } 16 | 17 | public Quadruplet createQuadruplet() { return null; } 18 | 19 | public static class Quadruplet {} 20 | } 21 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/Primitives.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.util.Random; 4 | 5 | public class Primitives { 6 | public static String app() { 7 | Random random = new Random(); 8 | byte a = (byte) random.nextInt(); 9 | short b = (short) random.nextInt(); 10 | int c = random.nextInt(); 11 | long d = random.nextLong(); 12 | char e = (char) random.nextInt(); 13 | float f = (float) random.nextDouble(); 14 | double g = (double) random.nextDouble(); 15 | boolean h = random.nextBoolean(); 16 | return "" + a + b + c + d + e + f + g + h; 17 | } 18 | 19 | public static void test() {} 20 | } 21 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/RawTypes.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | @SuppressWarnings("ALL") 7 | public class RawTypes { 8 | public static final List x = Collections.singletonList(42); 9 | } 10 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/SubClasses.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public class SubClasses extends AbstractClasses implements Interfaces { 4 | 5 | @Override 6 | public String abstractImplementation() { 7 | return "abstract"; 8 | } 9 | 10 | @Override 11 | public String abstractInterfaceMethod() { 12 | return "abstractInterface"; 13 | } 14 | 15 | public static String app() { 16 | SubClasses s = new SubClasses(); 17 | return s.abstractImplementation() 18 | + s.defaultImplementation() 19 | + s.abstractInterfaceMethod() 20 | + s.defaultInterfaceMethod(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/TabIndented.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public class TabIndented { 4 | public void app() { 5 | Object o = new Object() { 6 | @Override 7 | public boolean equals(Object other) { 8 | return false; 9 | } 10 | 11 | @Override 12 | public int hashCode() { 13 | return System.identityHashCode(this); 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return ""; 19 | } 20 | }; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/TypeAnnotations.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Target; 5 | 6 | @Target({ ElementType.TYPE_USE }) 7 | @interface TypeAnnotation { 8 | int integer() default 1; 9 | } 10 | 11 | // FIXME(issue: GRAPH-1122): Definition range for T below is incorrect 12 | class ClassProcessed<@TypeAnnotation T extends Number> { 13 | 14 | public ClassProcessed() { 15 | String s = new @TypeAnnotation String(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/minimized/src/main/java/minimized/TypeVariables.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | /** Example from https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.4 */ 4 | public class TypeVariables { 5 | static class C { 6 | public void mCPublic() {} 7 | 8 | protected void mCProtected() {} 9 | 10 | void mCPackage() {} 11 | } 12 | 13 | interface I { 14 | void mI(); 15 | } 16 | 17 | static class CT extends C implements I { 18 | public void mI() {} 19 | } 20 | 21 | public static void app(T t) { 22 | t.mI(); 23 | t.mCPublic(); 24 | t.mCProtected(); 25 | t.mCPackage(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/com/airbnb/epoxy/IllegalEpoxyUsage.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.epoxy; 2 | 3 | public class IllegalEpoxyUsage extends RuntimeException { 4 | // ^^^^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/IllegalEpoxyUsage# 5 | // display_name IllegalEpoxyUsage 6 | // signature_documentation java public class IllegalEpoxyUsage 7 | // kind Class 8 | // relationship is_implementation semanticdb maven jdk 11 java/io/Serializable# 9 | // relationship is_implementation semanticdb maven jdk 11 java/lang/Exception# 10 | // relationship is_implementation semanticdb maven jdk 11 java/lang/RuntimeException# 11 | // relationship is_implementation semanticdb maven jdk 11 java/lang/Throwable# 12 | // ^^^^^^^^^^^^^^^^ reference semanticdb maven jdk 11 java/lang/RuntimeException# 13 | public IllegalEpoxyUsage(String message) { 14 | // ^^^^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/IllegalEpoxyUsage#``(). 15 | // display_name 16 | // signature_documentation java public IllegalEpoxyUsage(String message) 17 | // kind Constructor 18 | // ^^^^^^ reference semanticdb maven jdk 11 java/lang/String# 19 | // ^^^^^^^ definition local 0 20 | // display_name message 21 | // signature_documentation java String message 22 | // enclosing_symbol semanticdb maven . . com/airbnb/epoxy/IllegalEpoxyUsage#``(). 23 | super(message); 24 | // ^^^^^ reference semanticdb maven jdk 11 java/lang/RuntimeException#``(+1). 25 | // ^^^^^^^ reference local 0 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/com/airbnb/epoxy/ModelCollector.kt: -------------------------------------------------------------------------------- 1 | package com.airbnb.epoxy 2 | // ^^^ reference semanticdb maven . . com/ 3 | // ^^^^^^ reference semanticdb maven . . com/airbnb/ 4 | // ^^^^^ reference semanticdb maven . . com/airbnb/epoxy/ 5 | 6 | /** 7 | * Interface used to collect models. Used by [EpoxyController]. It is also convenient to build DSL 8 | * helpers for carousel: @link https://github.com/airbnb/epoxy/issues/847. 9 | */ 10 | interface ModelCollector { 11 | // ^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/ModelCollector# 12 | // display_name ModelCollector 13 | // documentation ```kt\npublic interface ModelCollector\n```\n\n----\n\n\n Interface used to collect models. Used by [EpoxyController]. It is also convenient to build DSL\n helpers for carousel: @link https://github.com/airbnb/epoxy/issues/847.\n 14 | // relationship is_reference is_implementation semanticdb maven . . com/airbnb/epoxy/GroupModel# 15 | 16 | fun add(model: EpoxyModel<*>) 17 | // ^^^ definition semanticdb maven . . com/airbnb/epoxy/ModelCollector#add(). 18 | // display_name add 19 | // documentation ```kt\npublic abstract fun add(model: [Error type: Unresolved type for EpoxyModel<*>])\n``` 20 | // relationship is_reference is_implementation semanticdb maven . . com/airbnb/epoxy/GroupModel#add(). 21 | // ^^^^^ definition semanticdb maven . . com/airbnb/epoxy/ModelCollector#add().(model) 22 | // display_name model 23 | // documentation ```kt\nvalue-parameter model: [Error type: Unresolved type for EpoxyModel<*>]\n``` 24 | } 25 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpControllerHelper.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.epoxy; 2 | 3 | /** 4 | * A {@link ControllerHelper} implementation for adapters with no {@link 5 | * com.airbnb.epoxy.AutoModel} usage. 6 | */ 7 | class NoOpControllerHelper extends ControllerHelper { 8 | // ^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/NoOpControllerHelper# 9 | // display_name NoOpControllerHelper 10 | // signature_documentation java class NoOpControllerHelper 11 | // kind Class 12 | // documentation A {@link ControllerHelper} implementation for adapters with no {@link\n com.airbnb.epoxy.AutoModel} usage.\n 13 | // relationship is_implementation semanticdb maven . . com/airbnb/epoxy/ControllerHelper# 14 | // ^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/NoOpControllerHelper#``(). 15 | // display_name 16 | // signature_documentation java NoOpControllerHelper() 17 | // kind Constructor 18 | // ^^^^^^^^^^^^^^^^ reference semanticdb maven . . com/airbnb/epoxy/ControllerHelper# 19 | // ^^^^^^^^^^^^^^^ reference semanticdb maven . . com/airbnb/epoxy/EpoxyController# 20 | 21 | @Override 22 | // ^^^^^^^^ reference semanticdb maven jdk 11 java/lang/Override# 23 | public void resetAutoModels() { 24 | // ^^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/NoOpControllerHelper#resetAutoModels(). 25 | // display_name resetAutoModels 26 | // signature_documentation java @Override\npublic void resetAutoModels() 27 | // kind Method 28 | // relationship is_reference is_implementation semanticdb maven . . com/airbnb/epoxy/ControllerHelper#resetAutoModels(). 29 | // No - Op 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/com/airbnb/epoxy/NoOpTimer.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.epoxy; 2 | 3 | class NoOpTimer implements Timer { 4 | // ^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/NoOpTimer# 5 | // display_name NoOpTimer 6 | // signature_documentation java class NoOpTimer 7 | // kind Class 8 | // relationship is_implementation semanticdb maven . . com/airbnb/epoxy/Timer# 9 | // ^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/NoOpTimer#``(). 10 | // display_name 11 | // signature_documentation java NoOpTimer() 12 | // kind Constructor 13 | // ^^^^^ reference semanticdb maven . . com/airbnb/epoxy/Timer# 14 | @Override 15 | // ^^^^^^^^ reference semanticdb maven jdk 11 java/lang/Override# 16 | public void start(String sectionName) { 17 | // ^^^^^ definition semanticdb maven . . com/airbnb/epoxy/NoOpTimer#start(). 18 | // display_name start 19 | // signature_documentation java @Override\npublic void start(String sectionName) 20 | // kind Method 21 | // relationship is_reference is_implementation semanticdb maven . . com/airbnb/epoxy/Timer#start(). 22 | // ^^^^^^ reference semanticdb maven jdk 11 java/lang/String# 23 | // ^^^^^^^^^^^ definition local 0 24 | // display_name sectionName 25 | // signature_documentation java String sectionName 26 | // enclosing_symbol semanticdb maven . . com/airbnb/epoxy/NoOpTimer#start(). 27 | 28 | } 29 | 30 | @Override 31 | // ^^^^^^^^ reference semanticdb maven jdk 11 java/lang/Override# 32 | public void stop() { 33 | // ^^^^ definition semanticdb maven . . com/airbnb/epoxy/NoOpTimer#stop(). 34 | // display_name stop 35 | // signature_documentation java @Override\npublic void stop() 36 | // kind Method 37 | // relationship is_reference is_implementation semanticdb maven . . com/airbnb/epoxy/Timer#stop(). 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/com/airbnb/epoxy/OnModelBuildFinishedListener.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.epoxy; 2 | 3 | import androidx.annotation.NonNull; 4 | // ^^^^^^^^ reference semanticdb maven . . androidx/ 5 | // ^^^^^^^^^^ reference semanticdb maven . . androidx/annotation/ 6 | // ^^^^^^^ reference semanticdb maven maven/androidx.annotation/annotation 1.1.0 androidx/annotation/NonNull# 7 | 8 | /** 9 | * Used with {@link EpoxyController#addModelBuildListener(OnModelBuildFinishedListener)} to be 10 | * alerted to new model changes. 11 | */ 12 | public interface OnModelBuildFinishedListener { 13 | // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/OnModelBuildFinishedListener# 14 | // display_name OnModelBuildFinishedListener 15 | // signature_documentation java public interface OnModelBuildFinishedListener 16 | // kind Interface 17 | // documentation Used with {@link EpoxyController#addModelBuildListener(OnModelBuildFinishedListener)} to be\n alerted to new model changes.\n 18 | /** 19 | * Called after {@link EpoxyController#buildModels()} has run and changes have been notified to 20 | * the adapter. This will be called even if no changes existed. 21 | */ 22 | void onModelBuildFinished(@NonNull DiffResult result); 23 | // ^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/OnModelBuildFinishedListener#onModelBuildFinished(). 24 | // display_name onModelBuildFinished 25 | // signature_documentation java public abstract void onModelBuildFinished(DiffResult result) 26 | // kind AbstractMethod 27 | // documentation Called after {@link EpoxyController#buildModels()} has run and changes have been notified to\n the adapter. This will be called even if no changes existed.\n 28 | // ^^^^^^^ reference semanticdb maven maven/androidx.annotation/annotation 1.1.0 androidx/annotation/NonNull# 29 | // ^^^^^^^^^^ reference semanticdb maven . . com/airbnb/epoxy/DiffResult# 30 | // ^^^^^^ definition local 0 31 | // display_name result 32 | // signature_documentation java @NonNull\nDiffResult result 33 | // enclosing_symbol semanticdb maven . . com/airbnb/epoxy/OnModelBuildFinishedListener#onModelBuildFinished(). 34 | } 35 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/com/airbnb/epoxy/StyleBuilderCallback.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.epoxy; 2 | 3 | /** 4 | * Used for specifying dynamic styling for a view when creating a model. This is only used if the 5 | * view is set up to be styled with the Paris library. 6 | */ 7 | public interface StyleBuilderCallback { 8 | // ^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/StyleBuilderCallback# 9 | // display_name StyleBuilderCallback 10 | // signature_documentation java public interface StyleBuilderCallback 11 | // kind Interface 12 | // documentation Used for specifying dynamic styling for a view when creating a model. This is only used if the\n view is set up to be styled with the Paris library.\n 13 | // ^ definition semanticdb maven . . com/airbnb/epoxy/StyleBuilderCallback#[T] 14 | // display_name T 15 | // signature_documentation java T 16 | // kind TypeParameter 17 | void buildStyle(T builder); 18 | // ^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/StyleBuilderCallback#buildStyle(). 19 | // display_name buildStyle 20 | // signature_documentation java public abstract void buildStyle(T builder) 21 | // kind AbstractMethod 22 | // ^ reference semanticdb maven . . com/airbnb/epoxy/StyleBuilderCallback#[T] 23 | // ^^^^^^^ definition local 0 24 | // display_name builder 25 | // signature_documentation java T builder 26 | // enclosing_symbol semanticdb maven . . com/airbnb/epoxy/StyleBuilderCallback#buildStyle(). 27 | } 28 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/com/airbnb/epoxy/Timer.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.epoxy; 2 | 3 | interface Timer { 4 | // ^^^^^ definition semanticdb maven . . com/airbnb/epoxy/Timer# 5 | // display_name Timer 6 | // signature_documentation java interface Timer 7 | // kind Interface 8 | void start(String sectionName); 9 | // ^^^^^ definition semanticdb maven . . com/airbnb/epoxy/Timer#start(). 10 | // display_name start 11 | // signature_documentation java public abstract void start(String sectionName) 12 | // kind AbstractMethod 13 | // relationship is_reference is_implementation semanticdb maven . . com/airbnb/epoxy/DebugTimer#start(). 14 | // relationship is_reference is_implementation semanticdb maven . . com/airbnb/epoxy/NoOpTimer#start(). 15 | // ^^^^^^ reference semanticdb maven jdk 11 java/lang/String# 16 | // ^^^^^^^^^^^ definition local 0 17 | // display_name sectionName 18 | // signature_documentation java String sectionName 19 | // enclosing_symbol semanticdb maven . . com/airbnb/epoxy/Timer#start(). 20 | void stop(); 21 | // ^^^^ definition semanticdb maven . . com/airbnb/epoxy/Timer#stop(). 22 | // display_name stop 23 | // signature_documentation java public abstract void stop() 24 | // kind AbstractMethod 25 | // relationship is_reference is_implementation semanticdb maven . . com/airbnb/epoxy/DebugTimer#stop(). 26 | // relationship is_reference is_implementation semanticdb maven . . com/airbnb/epoxy/NoOpTimer#stop(). 27 | } 28 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/com/airbnb/epoxy/preload/Preloadable.kt: -------------------------------------------------------------------------------- 1 | package com.airbnb.epoxy.preload 2 | // ^^^ reference semanticdb maven . . com/ 3 | // ^^^^^^ reference semanticdb maven . . com/airbnb/ 4 | // ^^^^^ reference semanticdb maven . . com/airbnb/epoxy/ 5 | // ^^^^^^^ reference semanticdb maven . . com/airbnb/epoxy/preload/ 6 | 7 | import android.view.View 8 | 9 | /** 10 | * Declares Views that should be preloaded. This can either be implemented by a custom view or by an [EpoxyHolder]. 11 | * 12 | * The preloadable views can be recursive ie if [Preloadable.viewsToPreload] includes any views that are themselves Preloadable those nested 13 | * views will instead by used. 14 | */ 15 | interface Preloadable { 16 | // ^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/preload/Preloadable# 17 | // display_name Preloadable 18 | // documentation ```kt\npublic interface Preloadable\n```\n\n----\n\n\n Declares Views that should be preloaded. This can either be implemented by a custom view or by an [EpoxyHolder].\n\n The preloadable views can be recursive ie if [Preloadable.viewsToPreload] includes any views that are themselves Preloadable those nested\n views will instead by used.\n 19 | val viewsToPreload: List 20 | // ^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/preload/Preloadable#getViewsToPreload(). 21 | // display_name viewsToPreload 22 | // documentation ```kt\npublic abstract val viewsToPreload: kotlin.collections.List<[Error type: Unresolved type for View]>\n``` 23 | // ^^^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/preload/Preloadable#viewsToPreload. 24 | // display_name viewsToPreload 25 | // documentation ```kt\npublic abstract val viewsToPreload: kotlin.collections.List<[Error type: Unresolved type for View]>\n``` 26 | // ^^^^ reference semanticdb maven . . kotlin/collections/List# 27 | } 28 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/com/airbnb/epoxy/utils/utils.kt: -------------------------------------------------------------------------------- 1 | package com.airbnb.epoxy.utils 2 | // ^^^ reference semanticdb maven . . com/ 3 | // ^^^^^^ reference semanticdb maven . . com/airbnb/ 4 | // ^^^^^ reference semanticdb maven . . com/airbnb/epoxy/ 5 | // ^^^^^ reference semanticdb maven . . com/airbnb/epoxy/utils/ 6 | 7 | import android.content.Context 8 | import android.content.pm.ApplicationInfo 9 | 10 | @PublishedApi 11 | //^^^^^^^^^^^ reference semanticdb maven maven/org.jetbrains.kotlin/kotlin-stdlib 1.4.20-RC kotlin/PublishedApi#``(). 12 | internal val Context.isDebuggable: Boolean 13 | // ^^^^^^^^^^^^ definition semanticdb maven . . com/airbnb/epoxy/utils/utilsKt#isDebuggable. 14 | // display_name isDebuggable 15 | // documentation ```kt\ninternal val [Error type: Unresolved type for Context].isDebuggable: kotlin.Boolean\n``` 16 | // ^^^^^^^ reference semanticdb maven . . kotlin/Boolean# 17 | get() = (applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0 18 | // ^^^ definition semanticdb maven . . com/airbnb/epoxy/utils/utilsKt#getIsDebuggable(). 19 | // display_name get 20 | // documentation ```kt\ninternal fun [Error type: Unresolved type for Context].``(): kotlin.Boolean\n``` 21 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/tests/minimized-scala/src/main/scala/minimized/Issue397.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | // ^^^^^^^^^ definition semanticdb maven . . minimized/ 3 | 4 | class Issue397 { 5 | // ^^^^^^^^ definition semanticdb maven . . minimized/Issue397# 6 | // display_name Issue397 7 | // signature_documentation scala class Issue397 8 | // kind Class 9 | // ^ definition semanticdb maven . . minimized/Issue397#``(). 10 | // display_name 11 | // signature_documentation scala def this() 12 | // kind Constructor 13 | var blah = Set("abc") 14 | // ^^^^ definition semanticdb maven . . minimized/Issue397#blah(). 15 | // display_name blah 16 | // signature_documentation scala var blah: Set[String] 17 | // kind Method 18 | // ____ synthetic_definition semanticdb maven . . minimized/Issue397#`blah_=`(). 19 | // display_name blah_= 20 | // signature_documentation scala var blah_=(x$1: Set[String]): Unit 21 | // kind Method 22 | // relationship is_definition semanticdb maven . . minimized/Issue397#blah(). 23 | // ^^^ reference semanticdb maven . . scala/Predef.Set. 24 | // ^ reference semanticdb maven . . scala/collection/IterableFactory#apply(). 25 | blah = Set.empty[String] 26 | //^^^^ reference semanticdb maven . . minimized/Issue397#`blah_=`(). 27 | // ^^^ reference semanticdb maven . . scala/Predef.Set. 28 | // ^^^^^ reference semanticdb maven . . scala/collection/immutable/Set.empty(). 29 | // ^^^^^^ reference semanticdb maven . . scala/Predef.String# 30 | } 31 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/tests/minimized-scala/src/main/scala/minimized/Issue412.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | // ^^^^^^^^^ definition semanticdb maven . . minimized/ 3 | 4 | class Issue412 { 5 | // ^^^^^^^^ definition semanticdb maven . . minimized/Issue412# 6 | // display_name Issue412 7 | // signature_documentation scala class Issue412 8 | // kind Class 9 | // ^ definition semanticdb maven . . minimized/Issue412#``(). 10 | // display_name 11 | // signature_documentation scala def this() 12 | // kind Constructor 13 | val a: Int = 5 14 | // ^ definition semanticdb maven . . minimized/Issue412#a. 15 | // display_name a 16 | // signature_documentation scala val a: Int 17 | // kind Method 18 | // ^^^ reference semanticdb maven . . scala/Int# 19 | val b: Long = a 20 | // ^ definition semanticdb maven . . minimized/Issue412#b. 21 | // display_name b 22 | // signature_documentation scala val b: Long 23 | // kind Method 24 | // ^^^^ reference semanticdb maven . . scala/Long# 25 | // ^ reference semanticdb maven . . minimized/Issue412#a. 26 | 27 | def a(b: Long): Unit = { 28 | // ^ definition semanticdb maven . . minimized/Issue412#a(). 29 | // display_name a 30 | // signature_documentation scala def a(b: Long): Unit 31 | // kind Method 32 | // ^ definition semanticdb maven . . minimized/Issue412#a().(b) 33 | // display_name b 34 | // signature_documentation scala b: Long 35 | // kind Parameter 36 | // ^^^^ reference semanticdb maven . . scala/Long# 37 | // ^^^^ reference semanticdb maven . . scala/Unit# 38 | println(b) 39 | // ^^^^^^^ reference semanticdb maven . . scala/Predef.println(+1). 40 | // ^ reference semanticdb maven . . minimized/Issue412#a().(b) 41 | } 42 | a(a) 43 | //^ reference semanticdb maven . . minimized/Issue412#a(). 44 | // ^ reference semanticdb maven . . minimized/Issue412#a. 45 | 46 | } 47 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/tests/minimized-scala/src/main/scala/minimized/Issue414.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | // ^^^^^^^^^ definition semanticdb maven . . minimized/ 3 | 4 | object Issue414 { 5 | // ^^^^^^^^ definition semanticdb maven . . minimized/Issue414. 6 | // display_name Issue414 7 | // signature_documentation scala object Issue414 8 | // kind Object 9 | trait A { 10 | // ^ definition semanticdb maven . . minimized/Issue414.A# 11 | // display_name A 12 | // signature_documentation scala trait A 13 | // kind Trait 14 | def b(): Unit 15 | // ^ definition semanticdb maven . . minimized/Issue414.A#b(). 16 | // display_name b 17 | // signature_documentation scala def b(): Unit 18 | // kind AbstractMethod 19 | // ^^^^ reference semanticdb maven . . scala/Unit# 20 | } 21 | val a1 = 22 | // ^^ definition semanticdb maven . . minimized/Issue414.a1. 23 | // display_name a1 24 | // signature_documentation scala val a1: {} 25 | // kind Method 26 | new A { 27 | // ^ definition local 0 28 | // display_name $anon 29 | // signature_documentation scala final class $anon 30 | // kind Class 31 | // ^ reference semanticdb maven . . minimized/Issue414.A# 32 | // ^ reference semanticdb maven jdk 11 java/lang/Object#``(). 33 | override def b(): Unit = { 34 | // ^ definition local 1 35 | // display_name b 36 | // signature_documentation scala def b(): Unit 37 | // kind Method 38 | // relationship is_reference is_implementation semanticdb maven . . minimized/Issue414.A#b(). 39 | // ^^^^ reference semanticdb maven . . scala/Unit# 40 | print("Hello") 41 | // ^^^^^ reference semanticdb maven . . scala/Predef.print(). 42 | } 43 | } 44 | val a2: A = a1 45 | // ^^ definition semanticdb maven . . minimized/Issue414.a2. 46 | // display_name a2 47 | // signature_documentation scala val a2: A 48 | // kind Method 49 | // ^ reference semanticdb maven . . minimized/Issue414.A# 50 | // ^^ reference semanticdb maven . . minimized/Issue414.a1. 51 | println(a1.b()) 52 | //^^^^^^^ reference semanticdb maven . . scala/Predef.println(+1). 53 | // ^^ reference semanticdb maven . . minimized/Issue414.a1. 54 | // ^ reference semanticdb maven . . minimized/Issue414.A#b(). 55 | println(a2.b()) 56 | //^^^^^^^ reference semanticdb maven . . scala/Predef.println(+1). 57 | // ^^ reference semanticdb maven . . minimized/Issue414.a2. 58 | // ^ reference semanticdb maven . . minimized/Issue414.A#b(). 59 | } 60 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/tests/minimized-scala/src/main/scala/minimized/Issue414Reference.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | // ^^^^^^^^^ definition semanticdb maven . . minimized/ 3 | 4 | object Issue414Reference { 5 | // ^^^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/Issue414Reference. 6 | // display_name Issue414Reference 7 | // signature_documentation scala object Issue414Reference 8 | // kind Object 9 | println(Issue414.a1.b()) 10 | //^^^^^^^ reference semanticdb maven . . scala/Predef.println(+1). 11 | // ^^^^^^^^ reference semanticdb maven . . minimized/Issue414. 12 | // ^^ reference semanticdb maven . . minimized/Issue414.a1. 13 | // ^ reference semanticdb maven . . minimized/Issue414.A#b(). 14 | println(Issue414.a2.b()) 15 | //^^^^^^^ reference semanticdb maven . . scala/Predef.println(+1). 16 | // ^^^^^^^^ reference semanticdb maven . . minimized/Issue414. 17 | // ^^ reference semanticdb maven . . minimized/Issue414.a2. 18 | // ^ reference semanticdb maven . . minimized/Issue414.A#b(). 19 | } 20 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/tests/minimized-scala/src/main/scala/minimized/ReflectiveCall.scala: -------------------------------------------------------------------------------- 1 | package minimized 2 | // ^^^^^^^^^ definition semanticdb maven . . minimized/ 3 | 4 | import scala.language.reflectiveCalls 5 | // ^^^^^ reference semanticdb maven . . scala/ 6 | // ^^^^^^^^ reference semanticdb maven . . scala/language. 7 | // ^^^^^^^^^^^^^^^ reference semanticdb maven . . scala/language.reflectiveCalls. 8 | 9 | class ReflectiveCall { 10 | // ^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/ReflectiveCall# 11 | // display_name ReflectiveCall 12 | // signature_documentation scala class ReflectiveCall 13 | // kind Class 14 | // ^ definition semanticdb maven . . minimized/ReflectiveCall#``(). 15 | // display_name 16 | // signature_documentation scala def this() 17 | // kind Constructor 18 | // Reproduction for https://github.com/scalameta/scalameta/issues/2788 19 | val a = 20 | // ^ definition semanticdb maven . . minimized/ReflectiveCall#a. 21 | // display_name a 22 | // signature_documentation scala val a: { val b: Int } 23 | // kind Method 24 | new { 25 | // ^ definition local 0 26 | // display_name $anon 27 | // signature_documentation scala final class $anon 28 | // kind Class 29 | val b = 1 30 | // ^ definition local 1 31 | // display_name b 32 | // signature_documentation scala val b: Int 33 | // kind Method 34 | } 35 | println(a.b) 36 | //^^^^^^^ reference semanticdb maven . . scala/Predef.println(+1). 37 | // ^ reference semanticdb maven . . minimized/ReflectiveCall#a. 38 | // ^ reference local 1 39 | } 40 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/tests/minimized/src/main/java/minimized/AbstractClasses.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public abstract class AbstractClasses { 4 | // ^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses# 5 | // display_name AbstractClasses 6 | // signature_documentation java public abstract class AbstractClasses 7 | // kind Class 8 | // ^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#``(). 9 | // display_name 10 | // signature_documentation java public AbstractClasses() 11 | // kind Constructor 12 | public String defaultImplementation() { 13 | // ^^^^^^ reference semanticdb maven jdk 11 java/lang/String# 14 | // ^^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#defaultImplementation(). 15 | // display_name defaultImplementation 16 | // signature_documentation java public String defaultImplementation() 17 | // kind Method 18 | return ""; 19 | } 20 | 21 | public abstract String abstractImplementation(); 22 | // ^^^^^^ reference semanticdb maven jdk 11 java/lang/String# 23 | // ^^^^^^^^^^^^^^^^^^^^^^ definition semanticdb maven . . minimized/AbstractClasses#abstractImplementation(). 24 | // display_name abstractImplementation 25 | // signature_documentation java public abstract String abstractImplementation() 26 | // kind AbstractMethod 27 | // relationship is_reference is_implementation semanticdb maven . . minimized/SubClasses#abstractImplementation(). 28 | } 29 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/tests/minimized/src/main/java/minimized/Arrays.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public class Arrays { 4 | // ^^^^^^ definition semanticdb maven . . minimized/Arrays# 5 | // display_name Arrays 6 | // signature_documentation java public class Arrays 7 | // kind Class 8 | // ^^^^^^ definition semanticdb maven . . minimized/Arrays#``(). 9 | // display_name 10 | // signature_documentation java public Arrays() 11 | // kind Constructor 12 | public static String app() { 13 | // ^^^^^^ reference semanticdb maven jdk 11 java/lang/String# 14 | // ^^^ definition semanticdb maven . . minimized/Arrays#app(). 15 | // display_name app 16 | // signature_documentation java public static String app() 17 | // kind StaticMethod 18 | int[] a = {1, 2, 3}; 19 | // ^ definition local 0 20 | // display_name a 21 | // signature_documentation java int[] a 22 | // enclosing_symbol semanticdb maven . . minimized/Arrays#app(). 23 | // kind Variable 24 | String[] b = {"1", "2", "3"}; 25 | // ^^^^^^ reference semanticdb maven jdk 11 java/lang/String# 26 | // ^ definition local 1 27 | // display_name b 28 | // signature_documentation java String[] b 29 | // enclosing_symbol semanticdb maven . . minimized/Arrays#app(). 30 | // kind Variable 31 | int[][] c = {{1}, {2}, {3}}; 32 | // ^ definition local 2 33 | // display_name c 34 | // signature_documentation java int[][] c 35 | // enclosing_symbol semanticdb maven . . minimized/Arrays#app(). 36 | // kind Variable 37 | String[][] d = {{"1"}, {"2"}, {"3"}}; 38 | // ^^^^^^ reference semanticdb maven jdk 11 java/lang/String# 39 | // ^ definition local 3 40 | // display_name d 41 | // signature_documentation java String[][] d 42 | // enclosing_symbol semanticdb maven . . minimized/Arrays#app(). 43 | // kind Variable 44 | return b[0] + a[0] + c[1][0] + d[1][0]; 45 | // ^ reference local 1 46 | // ^ reference local 0 47 | // ^ reference local 2 48 | // ^ reference local 3 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/tests/minimized/src/main/java/minimized/ClassOf.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | public class ClassOf { 4 | // ^^^^^^^ definition semanticdb maven . . minimized/ClassOf# 5 | // display_name ClassOf 6 | // signature_documentation java public class ClassOf 7 | // kind Class 8 | // ^^^^^^^ definition semanticdb maven . . minimized/ClassOf#``(). 9 | // display_name 10 | // signature_documentation java public ClassOf() 11 | // kind Constructor 12 | public static String app() { 13 | // ^^^^^^ reference semanticdb maven jdk 11 java/lang/String# 14 | // ^^^ definition semanticdb maven . . minimized/ClassOf#app(). 15 | // display_name app 16 | // signature_documentation java public static String app() 17 | // kind StaticMethod 18 | return ClassOf.class.getName(); 19 | // ^^^^^^^ reference semanticdb maven . . minimized/ClassOf# 20 | // ^^^^^ reference semanticdb maven . . minimized/ClassOf#class. 21 | // ^^^^^^^ reference semanticdb maven jdk 11 java/lang/Class#getName(). 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/generated/tests/minimized/src/main/java/minimized/RawTypes.java: -------------------------------------------------------------------------------- 1 | package minimized; 2 | 3 | import java.util.Collections; 4 | // ^^^^ reference semanticdb maven . . java/ 5 | // ^^^^ reference semanticdb maven . . java/util/ 6 | // ^^^^^^^^^^^ reference semanticdb maven jdk 11 java/util/Collections# 7 | import java.util.List; 8 | // ^^^^ reference semanticdb maven . . java/ 9 | // ^^^^ reference semanticdb maven . . java/util/ 10 | // ^^^^ reference semanticdb maven jdk 11 java/util/List# 11 | 12 | @SuppressWarnings("ALL") 13 | //^^^^^^^^^^^^^^^ reference semanticdb maven jdk 11 java/lang/SuppressWarnings# 14 | public class RawTypes { 15 | // ^^^^^^^^ definition semanticdb maven . . minimized/RawTypes# 16 | // display_name RawTypes 17 | // signature_documentation java @SuppressWarnings("ALL")\npublic class RawTypes 18 | // kind Class 19 | // ^^^^^^^^ definition semanticdb maven . . minimized/RawTypes#``(). 20 | // display_name 21 | // signature_documentation java public RawTypes() 22 | // kind Constructor 23 | public static final List x = Collections.singletonList(42); 24 | // ^^^^ reference semanticdb maven jdk 11 java/util/List# 25 | // ^ definition semanticdb maven . . minimized/RawTypes#x. 26 | // display_name x 27 | // signature_documentation java public static final List x 28 | // kind StaticField 29 | // ^^^^^^^^^^^ reference semanticdb maven jdk 11 java/util/Collections# 30 | // ^^^^^^^^^^^^^ reference semanticdb maven jdk 11 java/util/Collections#singletonList(). 31 | } 32 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/AggregateSnapshotGenerator.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | class AggregateSnapshotGenerator(underlying: List[SnapshotGenerator]) 4 | extends SnapshotGenerator { 5 | override def run(context: SnapshotContext, handler: SnapshotHandler): Unit = { 6 | underlying.foreach { generator => 7 | generator.run(context, handler.withoutFinishedEvent) 8 | } 9 | handler.onFinished(context) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/AssertSnapshotHandlers.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.nio.charset.StandardCharsets 4 | import java.nio.file.Files 5 | import java.nio.file.Path 6 | 7 | import munit.FailException 8 | import munit.FunSuite 9 | import munit.Location 10 | 11 | /** 12 | * Helper class to create test suite from a snapshot generator. 13 | */ 14 | trait AssertSnapshotHandlers { 15 | self: FunSuite => 16 | 17 | class AssertSnapshotHandler extends SnapshotHandler { 18 | override def onSnapshotTest( 19 | context: SnapshotContext, 20 | expectFile: Path, 21 | obtainedOutput: () => String 22 | ): Unit = { 23 | val relativePath = context.expectDirectory.relativize(expectFile) 24 | self.test(relativePath.toString) { 25 | if (Files.isRegularFile(expectFile)) { 26 | val expected = 27 | new String(Files.readAllBytes(expectFile), StandardCharsets.UTF_8) 28 | self.assertNoDiff(obtainedOutput(), expected) 29 | } else { 30 | throw new FailException( 31 | s"no snapshot file. To fix this problem, execute the command 'sbt snapshots/run'", 32 | cause = null, 33 | isStackTracesEnabled = false, 34 | location = Location.empty 35 | ) 36 | } 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/LibrarySnapshotGenerator.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.io.ByteArrayOutputStream 4 | import java.io.PrintStream 5 | import java.nio.charset.StandardCharsets 6 | import java.nio.file.FileSystems 7 | import java.nio.file.FileVisitResult 8 | import java.nio.file.Files 9 | import java.nio.file.Path 10 | import java.nio.file.SimpleFileVisitor 11 | import java.nio.file.attribute.BasicFileAttributes 12 | 13 | import scala.util.Properties 14 | 15 | import com.sourcegraph.scip_java.ScipJava 16 | import moped.reporters.ConsoleReporter 17 | 18 | class LibrarySnapshotGenerator extends SnapshotGenerator { 19 | val scalaPattern = FileSystems.getDefault.getPathMatcher("glob:**.scala") 20 | val javaPattern = FileSystems.getDefault.getPathMatcher("glob:**.java") 21 | def runScipJava(arguments: List[String]): Unit = { 22 | val baos = new ByteArrayOutputStream 23 | val exitCode = ScipJava 24 | .app 25 | .withReporter(ConsoleReporter(new PrintStream(baos))) 26 | .withEnv( 27 | ScipJava 28 | .app 29 | .env 30 | .withStandardOutput(new PrintStream(baos)) 31 | .withStandardError(new PrintStream(baos)) 32 | .withExit(i => throw new RuntimeException(i.toString())) 33 | ) 34 | .run(arguments) 35 | if (exitCode != 0) { 36 | throw new RuntimeException(baos.toString()) 37 | } 38 | } 39 | 40 | override def run(context: SnapshotContext, handler: SnapshotHandler): Unit = { 41 | val gen = new Gen(context, handler) 42 | gen.checkLibrary("com.airbnb.android:epoxy:4.3.1") 43 | gen.checkLibrary( 44 | "com.lihaoyi:ujson_2.13:1.4.0", 45 | provided = List( 46 | s"org.scala-lang:scala-library:${Properties.versionNumberString}" 47 | ) 48 | ) 49 | } 50 | 51 | private class Gen(context: SnapshotContext, handler: SnapshotHandler) { 52 | def checkLibrary(name: String, provided: List[String] = Nil): Unit = { 53 | println(s"indexing library '$name'") 54 | val providedArguments = provided.flatMap(p => List("--provided", p)) 55 | val snapshotDir = Files.createTempDirectory("semanticdb-javac") 56 | runScipJava( 57 | List( 58 | "index-dependency", 59 | "--no-cleanup", 60 | "--snapshot", 61 | "--dependency", 62 | name, 63 | "--output", 64 | snapshotDir.toString() 65 | ) ++ providedArguments 66 | ) 67 | val root = snapshotDir.toFile().listFiles().head.toPath() 68 | Files.walkFileTree( 69 | root, 70 | new SimpleFileVisitor[Path] { 71 | override def visitFile( 72 | file: Path, 73 | attrs: BasicFileAttributes 74 | ): FileVisitResult = { 75 | val print = 76 | new String(Files.readAllBytes(file), StandardCharsets.UTF_8) 77 | val out = context.expectDirectory.resolve(root.relativize(file)) 78 | handler.onSnapshotTest(context, out, () => print) 79 | super.visitFile(file, attrs) 80 | } 81 | } 82 | ) 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/MinimizedSnapshotScipGenerator.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.net.URI 4 | import java.nio.charset.StandardCharsets 5 | import java.nio.file.Files 6 | import java.nio.file.Paths 7 | 8 | import scala.jdk.CollectionConverters.CollectionHasAsScala 9 | 10 | import scala.meta.internal.io.FileIO 11 | import scala.meta.io.AbsolutePath 12 | 13 | import com.sourcegraph.Scip.Index 14 | import com.sourcegraph.io.DeleteVisitor 15 | import com.sourcegraph.scip_java.ScipJava 16 | import com.sourcegraph.scip_java.ScipPrinters 17 | 18 | class MinimizedSnapshotScipGenerator extends SnapshotGenerator { 19 | def run(args: List[String]): Unit = { 20 | val exit = ScipJava.app.run(args) 21 | require(exit == 0) 22 | } 23 | def onFinished(context: SnapshotContext): Unit = () 24 | override def run(context: SnapshotContext, handler: SnapshotHandler): Unit = { 25 | onTargetroot( 26 | context, 27 | handler, 28 | AbsolutePath(BuildInfo.minimizedJavaTargetroot), 29 | AbsolutePath(BuildInfo.minimizedJavaSourceDirectory) 30 | ) 31 | onTargetroot( 32 | context, 33 | handler, 34 | AbsolutePath(BuildInfo.minimizedScalaTargetroot), 35 | AbsolutePath(BuildInfo.minimizedScalaSourceDirectory) 36 | ) 37 | } 38 | def onTargetroot( 39 | context: SnapshotContext, 40 | handler: SnapshotHandler, 41 | targetroot: AbsolutePath, 42 | sourceDirectory: AbsolutePath 43 | ): Unit = { 44 | val sourceroot = AbsolutePath(BuildInfo.sourceroot) 45 | val scipOutput = Files 46 | .createTempDirectory("scip-java") 47 | .resolve("index.scip") 48 | val snapshotOutput = AbsolutePath(Files.createTempDirectory("scip-java")) 49 | run( 50 | List( 51 | "index-semanticdb", 52 | "--cwd", 53 | sourceroot.toString(), 54 | "--output", 55 | scipOutput.toString, 56 | "--targetroot", 57 | targetroot.toString() 58 | ) 59 | ) 60 | val index = Index.parseFrom(Files.readAllBytes(scipOutput)) 61 | try { 62 | index 63 | .getDocumentsList 64 | .asScala 65 | .foreach { document => 66 | val expectOutput = context 67 | .expectDirectory 68 | .resolve(Paths.get(document.getRelativePath)) 69 | handler.onSnapshotTest( 70 | context, 71 | expectOutput, 72 | () => { 73 | val uri = URI.create( 74 | List( 75 | index.getMetadata.getProjectRoot.stripSuffix("/"), 76 | document.getRelativePath 77 | ).mkString("/") 78 | ) 79 | 80 | val absolutePath = AbsolutePath(Paths.get(uri)) 81 | val text = FileIO.slurp(absolutePath, StandardCharsets.UTF_8) 82 | ScipPrinters.printTextDocument(document, text) 83 | } 84 | ) 85 | } 86 | } finally { 87 | Files.walkFileTree(scipOutput, new DeleteVisitor()) 88 | Files.walkFileTree(snapshotOutput.toNIO, new DeleteVisitor()) 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/SaveSnapshotHandler.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.nio.charset.StandardCharsets 4 | import java.nio.file.Files 5 | import java.nio.file.Path 6 | import java.util.concurrent.ConcurrentLinkedDeque 7 | 8 | import scala.jdk.CollectionConverters._ 9 | 10 | import com.sourcegraph.io.DeleteVisitor 11 | 12 | class SaveSnapshotHandler extends SnapshotHandler { 13 | private val writtenTests = new ConcurrentLinkedDeque[Path]() 14 | override def onSnapshotTest( 15 | context: SnapshotContext, 16 | expectFile: Path, 17 | obtainedOutput: () => String 18 | ): Unit = { 19 | Files.createDirectories(expectFile.getParent) 20 | Files.write(expectFile, obtainedOutput().getBytes(StandardCharsets.UTF_8)) 21 | writtenTests.add(expectFile) 22 | } 23 | 24 | override def onFinished(context: SnapshotContext): Unit = { 25 | if (!Files.exists(context.expectDirectory)) { 26 | return 27 | } 28 | val isWritten = writtenTests.asScala.toSet 29 | Files.walkFileTree( 30 | context.expectDirectory, 31 | new DeleteVisitor(deleteFile = file => !isWritten.contains(file)) 32 | ) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/SaveSnapshots.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | object SaveSnapshots { 4 | def main(args: Array[String]): Unit = { 5 | val expectDirectory = tests.snapshots.BuildInfo.snapshotDirectory.toPath 6 | val mapping = Map( 7 | "minimized" -> new MinimizedSnapshotScipGenerator(), 8 | "library" -> new LibrarySnapshotGenerator() 9 | ) 10 | 11 | val enabledGenerators = 12 | if (args.isEmpty) 13 | mapping.values.toList 14 | else 15 | args.flatMap(mapping.get).toList 16 | 17 | val generator = new AggregateSnapshotGenerator(enabledGenerators) 18 | 19 | generator.run(SnapshotContext(expectDirectory), new SaveSnapshotHandler) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/SemanticdbFile.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.nio.file.Files 4 | 5 | import scala.meta.internal.io.FileIO 6 | import scala.meta.io.AbsolutePath 7 | import scala.meta.io.RelativePath 8 | 9 | import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocument 10 | import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocuments 11 | 12 | case class SemanticdbFile( 13 | sourceroot: AbsolutePath, 14 | relativePath: RelativePath, 15 | sourceDirectory: AbsolutePath, 16 | targetroot: AbsolutePath 17 | ) { 18 | def javaPath: AbsolutePath = sourceroot.resolve(relativePath) 19 | def semanticdbPath: AbsolutePath = 20 | targetroot 21 | .resolve("META-INF") 22 | .resolve("semanticdb") 23 | .resolve(relativePath.toString() + ".semanticdb") 24 | def textDocument: TextDocument = { 25 | val docs = TextDocuments.parseFrom(Files.readAllBytes(semanticdbPath.toNIO)) 26 | if (docs.getDocumentsCount == 0) 27 | TextDocument.newBuilder().build() 28 | else 29 | docs.getDocuments(0) 30 | } 31 | } 32 | 33 | object SemanticdbFile { 34 | def fromDirectory( 35 | sourceDirectory: AbsolutePath, 36 | sourceroot: AbsolutePath, 37 | targetroot: AbsolutePath 38 | ): Seq[SemanticdbFile] = { 39 | FileIO 40 | .listAllFilesRecursively(sourceDirectory) 41 | .map { file => 42 | SemanticdbFile( 43 | sourceroot, 44 | file.toRelative(sourceroot), 45 | sourceDirectory, 46 | targetroot 47 | ) 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/SemanticdbJavacSnapshotGenerator.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | object SemanticdbJavacSnapshotGenerator 4 | extends AggregateSnapshotGenerator( 5 | List(new LibrarySnapshotGenerator(), new MinimizedSnapshotScipGenerator()) 6 | ) 7 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/SnapshotContext.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.nio.file.Path 4 | 5 | case class SnapshotContext(expectDirectory: Path) 6 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/SnapshotGenerator.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | trait SnapshotGenerator { 4 | def run(context: SnapshotContext, handler: SnapshotHandler): Unit 5 | } 6 | -------------------------------------------------------------------------------- /tests/snapshots/src/main/scala/tests/SnapshotHandler.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.nio.file.Path 4 | 5 | abstract class SnapshotHandler { 6 | self => 7 | def onSnapshotTest( 8 | context: SnapshotContext, 9 | expectFile: Path, 10 | obtainedOutput: () => String 11 | ): Unit = () 12 | def onFinished(context: SnapshotContext): Unit = () 13 | final def withoutFinishedEvent: SnapshotHandler = 14 | new SnapshotHandler { 15 | override def onFinished(context: SnapshotContext): Unit = () // Do nothing 16 | override def onSnapshotTest( 17 | context: SnapshotContext, 18 | expectFile: Path, 19 | obtainedOutput: () => String 20 | ): Unit = { 21 | self.onSnapshotTest(context, expectFile, obtainedOutput) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/snapshots/src/test/scala/tests/SnapshotSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import munit.FunSuite 4 | 5 | abstract class SnapshotSuite(generator: SnapshotGenerator) 6 | extends FunSuite 7 | with AssertSnapshotHandlers { 8 | generator.run( 9 | SnapshotContext(tests.snapshots.BuildInfo.snapshotDirectory.toPath), 10 | new AssertSnapshotHandler 11 | ) 12 | } 13 | 14 | class LibrarySnapshotSuite extends SnapshotSuite(new LibrarySnapshotGenerator) 15 | 16 | class MinimizedSnapshotScipSuite 17 | extends SnapshotSuite(new MinimizedSnapshotScipGenerator) 18 | -------------------------------------------------------------------------------- /tests/unit/src/main/scala/tests/CompileResult.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import com.sourcegraph.semanticdb_javac.Semanticdb 4 | 5 | case class CompileResult( 6 | byteCode: Array[Byte], 7 | stdout: String, 8 | textDocuments: Semanticdb.TextDocuments, 9 | isSuccess: Boolean 10 | ) { 11 | def textDocument: Option[Semanticdb.TextDocument] = { 12 | Option.when(textDocuments.getDocumentsCount() > 0) { 13 | textDocuments.getDocuments(0) 14 | } 15 | } 16 | 17 | def merge(other: CompileResult): CompileResult = { 18 | copy( 19 | byteCode = this.byteCode ++ other.byteCode, 20 | stdout = this.stdout ++ other.stdout, 21 | textDocuments = this 22 | .textDocuments 23 | .toBuilder 24 | .addAllDocuments(other.textDocuments.getDocumentsList) 25 | .build(), 26 | isSuccess = this.isSuccess && other.isSuccess 27 | ) 28 | } 29 | } 30 | 31 | object CompileResult { 32 | val empty: CompileResult = CompileResult( 33 | Array.emptyByteArray, 34 | "", 35 | Semanticdb.TextDocuments.getDefaultInstance, 36 | isSuccess = true 37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /tests/unit/src/main/scala/tests/SimpleClassFile.java: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import javax.tools.SimpleJavaFileObject; 4 | import java.io.ByteArrayOutputStream; 5 | import java.io.IOException; 6 | import java.io.OutputStream; 7 | import java.net.URI; 8 | 9 | public class SimpleClassFile extends SimpleJavaFileObject { 10 | 11 | private ByteArrayOutputStream out; 12 | 13 | public SimpleClassFile(URI uri) { 14 | super(uri, Kind.CLASS); 15 | } 16 | 17 | @Override 18 | public OutputStream openOutputStream() throws IOException { 19 | return out = new ByteArrayOutputStream(); 20 | } 21 | 22 | public byte[] getCompiledBinaries() { 23 | return out.toByteArray(); 24 | } 25 | 26 | // getters 27 | } 28 | 29 | -------------------------------------------------------------------------------- /tests/unit/src/main/scala/tests/SimpleFileManager.java: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import java.net.URI; 4 | import java.nio.file.Path; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import javax.tools.FileObject; 8 | import javax.tools.ForwardingJavaFileManager; 9 | import javax.tools.JavaFileObject; 10 | import javax.tools.StandardJavaFileManager; 11 | 12 | import com.sourcegraph.semanticdb_javac.SemanticdbPlugin; 13 | 14 | public class SimpleFileManager extends ForwardingJavaFileManager { 15 | 16 | public final List compiled = new ArrayList<>(); 17 | public final Path targetroot; 18 | 19 | protected SimpleFileManager(StandardJavaFileManager fileManager, Path targetroot) { 20 | super(fileManager); 21 | this.targetroot = targetroot; 22 | } 23 | 24 | // standard constructors/getters 25 | 26 | @Override 27 | public JavaFileObject getJavaFileForOutput( 28 | Location location, String className, JavaFileObject.Kind kind, FileObject sibling) { 29 | URI uri = targetroot.resolve(className).toUri(); 30 | SimpleClassFile result = new SimpleClassFile(uri); 31 | if (!className.equals(SemanticdbPlugin.stubClassName)) { 32 | compiled.add(result); 33 | } 34 | return result; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/unit/src/main/scala/tests/SimpleSourceFile.java: -------------------------------------------------------------------------------- 1 | package tests; 2 | 3 | import javax.tools.SimpleJavaFileObject; 4 | import java.net.URI; 5 | import java.nio.file.Path; 6 | 7 | public class SimpleSourceFile extends SimpleJavaFileObject { 8 | private final String content; 9 | 10 | public SimpleSourceFile(Path path, String testSource) { 11 | super(path.toUri(), Kind.SOURCE); 12 | content = testSource; 13 | } 14 | 15 | @Override 16 | public CharSequence getCharContent(boolean ignoreEncodingErrors) { 17 | return content; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/unit/src/main/scala/tests/TempDirectories.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.nio.file.Files 4 | import java.nio.file.Path 5 | 6 | import com.sourcegraph.io.DeleteVisitor 7 | import munit.FunSuite 8 | 9 | trait TempDirectories { 10 | self: FunSuite => 11 | 12 | class DirectoryFixture extends Fixture[Path]("DirectoryFixture") { 13 | private var path: Path = _ 14 | override def apply(): Path = path 15 | 16 | override def beforeEach(context: BeforeEach): Unit = { 17 | path = Files.createTempDirectory("semanticdb-javac") 18 | } 19 | 20 | override def afterEach(context: AfterEach): Unit = { 21 | Files.walkFileTree(path, new DeleteVisitor()) 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tests/unit/src/main/scala/tests/Timer.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.time.Clock 4 | import java.time.Duration 5 | import java.time.Instant 6 | import java.time.temporal.ChronoUnit 7 | import java.util.concurrent.TimeUnit 8 | 9 | class Timer(val clock: Clock = Clock.systemDefaultZone()) { 10 | val start: Instant = clock.instant() 11 | 12 | def instant(): Instant = clock.instant() 13 | def duration(): Duration = Duration.between(start, clock.instant()) 14 | 15 | def format(): String = Timer.formatDuration(start, clock.instant()) 16 | def formatPadded(): String = 17 | Timer.formatDurationPadded(start, clock.instant()) 18 | override def toString: String = format() 19 | } 20 | 21 | object Timer { 22 | def formatDurationPadded(start: Instant, end: Instant): String = 23 | formatDuration(start, end).padTo("10.4s".length(), ' ') 24 | 25 | def formatDuration(start: Instant, end: Instant): String = { 26 | val ms = ChronoUnit.MILLIS.between(start, end) 27 | val days = TimeUnit.MILLISECONDS.toDays(ms) 28 | val hr = TimeUnit.MILLISECONDS.toHours(ms) % 24 29 | val min = TimeUnit.MILLISECONDS.toMinutes(ms) % 60 30 | val s = (ms.toDouble / 1000) % 60 31 | new StringBuilder() 32 | .append( 33 | if (days <= 0) 34 | "" 35 | else if (days == 1) 36 | s"${days}day" 37 | else 38 | s"${days}days" 39 | ) 40 | .append( 41 | if (hr > 0) 42 | s"${hr}hr" 43 | else 44 | "" 45 | ) 46 | .append( 47 | if (min > 0) 48 | s"${min}m" 49 | else 50 | "" 51 | ) 52 | .append(f"$s%.1fs") 53 | .toString() 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /tests/unit/src/test/scala/tests/GeneratedConstructorSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import scala.meta.inputs.Input 4 | 5 | import com.sourcegraph.semanticdb_javac.Semanticdb.TextDocument 6 | import munit.FunSuite 7 | import munit.TestOptions 8 | 9 | class GeneratedConstructorSuite extends FunSuite with TempDirectories { 10 | val targetroot = new DirectoryFixture() 11 | 12 | override def munitFixtures: Seq[Fixture[_]] = 13 | super.munitFixtures ++ List(targetroot) 14 | 15 | def doSomething( 16 | options: TestOptions, 17 | original: String, 18 | fn: (TextDocument, List[String]) => Unit, 19 | qualifiedClassName: String = "example.Test" 20 | )(implicit loc: munit.Location): Unit = { 21 | test(options) { 22 | val groups = "<<([0-9a-zA-Z]+)>>".r 23 | val compiler = new TestCompiler(targetroot()) 24 | val trimmedText = groups.replaceAllIn(original, "$1") 25 | val relativePath = qualifiedClassName.replace('.', '/') + ".java" 26 | val input = Input.VirtualFile(relativePath, trimmedText) 27 | 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/unit/src/test/scala/tests/JavaVersionSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import com.sourcegraph.scip_semanticdb.JavaVersion 4 | import munit.FunSuite 5 | import munit.TestOptions 6 | 7 | class JavaVersionSuite extends FunSuite { 8 | def checkVersion(original: TestOptions, expected: String): Unit = { 9 | test(original) { 10 | val obtained = new JavaVersion(original.name) 11 | assertNoDiff(obtained.pkg.version, expected) 12 | } 13 | } 14 | 15 | checkVersion("1.8.0_272", "8") 16 | checkVersion("11.0.9", "11") 17 | 18 | } 19 | -------------------------------------------------------------------------------- /tests/unit/src/test/scala/tests/JavacClassesDirectorySuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.nio.file.Files 4 | import java.nio.file.Paths 5 | 6 | import scala.meta.inputs.Input 7 | 8 | import munit.FunSuite 9 | 10 | class JavacClassesDirectorySuite extends FunSuite with TempDirectories { 11 | val sourceroot = new DirectoryFixture() 12 | 13 | override def munitFixtures: Seq[Fixture[_]] = 14 | super.munitFixtures ++ List(sourceroot) 15 | 16 | test("targetroot:javac-classes-directory") { 17 | val compiler = 18 | new TestCompiler( 19 | classpath = TestCompiler.PROCESSOR_PATH, 20 | javacOptions = Nil, 21 | scalacOptions = Nil, 22 | targetroot = sourceroot(), 23 | sourceroot = sourceroot() 24 | ) 25 | val compileResult = compiler.compile( 26 | List( 27 | Input.VirtualFile( 28 | "example/Example.java", 29 | """package example; 30 | |public class Example{}""".stripMargin 31 | ) 32 | ), 33 | List( 34 | s"-Xplugin:semanticdb -sourceroot:${sourceroot()} -targetroot:javac-classes-directory", 35 | "-d", 36 | sourceroot().toString 37 | ) 38 | ) 39 | assert(clue(compileResult).isSuccess) 40 | val semanticdbPath = Paths 41 | .get("META-INF") 42 | .resolve("semanticdb") 43 | .resolve("example") 44 | .resolve("Example.java.semanticdb") 45 | assert(Files.isRegularFile(clue(sourceroot().resolve(semanticdbPath)))) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /tests/unit/src/test/scala/tests/SbtSupportedVersionsSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import com.sourcegraph.scip_java.buildtools.SbtBuildTool 4 | import com.sourcegraph.scip_java.buildtools.SbtVersionParser 5 | 6 | class SbtVersionParserSuite extends munit.FunSuite { 7 | test("parsing sbt versions") { 8 | import SbtVersionParser.{versionSegments => parse} 9 | assertEquals(parse("1.9.7"), List(1, 9, 7)) 10 | assertEquals(parse("1.10.0"), List(1, 10, 0)) 11 | assertEquals(parse("1.10.0-RC1"), List(1, 10, 0)) 12 | assertEquals(parse("0.13.17"), List(0, 13, 17)) 13 | assertEquals(parse("0.13"), List(0, 13)) 14 | } 15 | 16 | test("supported sbt versions") { 17 | import SbtBuildTool.{isSupportedSbtVersion => check} 18 | 19 | def checkSupported(version: String) = { 20 | assert(check(version).contains(true), check(version)) 21 | } 22 | 23 | def checkUnsupported(version: String) = { 24 | assert(check(version).contains(false), check(version)) 25 | } 26 | 27 | def checkFailed(version: String) = { 28 | assert(check(version).isLeft, check(version)) 29 | } 30 | 31 | checkSupported("1.10.0-RC1") 32 | checkSupported("0.13.17") 33 | checkSupported("1.5.6") 34 | checkSupported("1.9.7") 35 | 36 | checkUnsupported("1.0.0-RC1") 37 | checkUnsupported("0.13.16") 38 | checkUnsupported("1.1.6") 39 | checkUnsupported("0.12.15") 40 | 41 | checkFailed("1.0-RC1") 42 | checkFailed("0.13") 43 | checkFailed("BLA") 44 | checkFailed("") 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /tests/unit/src/test/scala/tests/ScalaVersionSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import java.nio.file.Paths 4 | 5 | import com.sourcegraph.scip_java.buildtools.ScalaVersion 6 | import com.sourcegraph.scip_java.{BuildInfo => V} 7 | import munit.FunSuite 8 | import munit.TestOptions 9 | 10 | class ScalaVersionSuite extends FunSuite { 11 | def checkNone(original: TestOptions): Unit = { 12 | test(original) { 13 | assertEquals(ScalaVersion.inferFromJar(Paths.get(original.name)), None) 14 | } 15 | } 16 | def check(original: TestOptions, expected: String): Unit = { 17 | test(original) { 18 | val Some(obtained) = ScalaVersion.inferFromJar(Paths.get(original.name)) 19 | assertNoDiff(obtained, expected) 20 | } 21 | } 22 | 23 | checkNone("junit-4.13.2") 24 | checkNone("scala-library-2.10.1.jar") 25 | check("scala-library-2.11.1.jar", V.scala211) 26 | check("scala-library-2.12.1.jar", V.scala212) 27 | check("scala-compiler-2.13.1.jar", V.scala213) 28 | check("scala-reflect-2.13.1.jar", V.scala213) 29 | check("scala-library-2.13.1.jar", V.scala213) 30 | check("scalap-2.13.1.jar", V.scala213) 31 | checkNone("scala-library-2.14.1.jar") 32 | 33 | check("geny_2.11-0.10.5.jar", V.scala211) 34 | check("geny_2.12-0.10.5.jar", V.scala212) 35 | check("geny_2.13-0.10.5.jar", V.scala213) 36 | check("geny_3-0.10.5.jar", V.scala3) 37 | 38 | } 39 | -------------------------------------------------------------------------------- /tests/unit/src/test/scala/tests/SymbolDescriptorSuite.scala: -------------------------------------------------------------------------------- 1 | package tests 2 | 3 | import scala.meta.internal.semanticdb.Scala._ 4 | 5 | import com.sourcegraph.scip_semanticdb.SymbolDescriptor 6 | import com.sourcegraph.semanticdb_javac.SemanticdbSymbols.Descriptor.Kind 7 | import munit.FunSuite 8 | import munit.TestOptions 9 | 10 | class SymbolDescriptorSuite extends FunSuite { 11 | def checkDescriptor(options: TestOptions): Unit = { 12 | test(options) { 13 | val original = options.name 14 | val obtained = SymbolDescriptor.parseFromSymbol(original); 15 | val expectedKind = 16 | original.desc match { 17 | case Descriptor.None => 18 | Kind.None 19 | case Descriptor.Term(value) => 20 | Kind.Term 21 | case Descriptor.Method(value, disambiguator) => 22 | Kind.Method 23 | case Descriptor.Type(value) => 24 | Kind.Type 25 | case Descriptor.Package(value) => 26 | Kind.Package 27 | case Descriptor.Parameter(value) => 28 | Kind.Parameter 29 | case Descriptor.TypeParameter(value) => 30 | Kind.TypeParameter 31 | } 32 | assertEquals(obtained.descriptor.name, original.desc.value, original) 33 | assertEquals(obtained.owner, original.owner, original) 34 | assertEquals(obtained.descriptor.kind, expectedKind, original) 35 | } 36 | } 37 | checkDescriptor("Test#") 38 | checkDescriptor("sample/Test#") 39 | checkDescriptor("sample/Test#m1().") 40 | checkDescriptor("sample/Test#m1().(t1)") 41 | checkDescriptor("sample/Test#m1().[T1]") 42 | checkDescriptor("sample/Test#field.") 43 | checkDescriptor("sample/Test#``().") 44 | checkDescriptor("sample/Test#Inner#") 45 | checkDescriptor("sample/") 46 | } 47 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | blog/ 2 | -------------------------------------------------------------------------------- /website/.tool-versions: -------------------------------------------------------------------------------- 1 | yarn 1.22.4 2 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # SCIP-Java Website 2 | 3 | ## Setup 4 | 5 | ```bash 6 | $ git@github.com:sourcegraph/scip-java.git 7 | $ cd scip-java/ 8 | $ yarn install 9 | ``` 10 | 11 | ## Start 12 | 13 | ```bash 14 | # In one terminal window, requires a Java installation 15 | $ ./sbt "docs/mdoc -w" 16 | # In a separate terminal window 17 | $ cd website/ 18 | $ yarn run start 19 | ``` 20 | 21 | ## Troubleshoot 22 | 23 | ```bash 24 | $ yarn global add docusaurus --dev 25 | ``` -------------------------------------------------------------------------------- /website/core/Footer.js: -------------------------------------------------------------------------------- 1 | const React = require("react"); 2 | 3 | const siteConfig = require(process.cwd() + "/siteConfig.js"); 4 | 5 | class Footer extends React.Component { 6 | render() { 7 | const { 8 | baseUrl, 9 | copyright, 10 | colors: { secondaryColor } 11 | } = this.props.config; 12 | const docsUrl = `${baseUrl}docs/`; 13 | return ( 14 |

51 | ); 52 | } 53 | } 54 | 55 | module.exports = Footer; 56 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "examples": "docusaurus-examples", 4 | "start": "docusaurus-start", 5 | "build": "docusaurus-build", 6 | "publish-gh-pages": "docusaurus-publish", 7 | "write-translations": "docusaurus-write-translations", 8 | "version": "docusaurus-version", 9 | "rename-version": "docusaurus-rename-version" 10 | }, 11 | "devDependencies": { 12 | "docusaurus": "1.14.7" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /website/project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.10.10 2 | -------------------------------------------------------------------------------- /website/sidebars.json: -------------------------------------------------------------------------------- 1 | { 2 | "docs": { 3 | "Using": [ 4 | "getting-started", 5 | "manual-configuration" 6 | ], 7 | "Contributing": [ 8 | "contributing", 9 | "design", 10 | "benchmarks" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /website/siteConfig.js: -------------------------------------------------------------------------------- 1 | // See https://docusaurus.io/docs/site-config.html for all the possible 2 | // site configuration options. 3 | 4 | const repoUrl = "https://github.com/sourcegraph/scip-java"; 5 | const baseUrl = "/scip-java/"; 6 | 7 | const siteConfig = { 8 | title: "scip-java", 9 | tagline: "Java indexer for the SCIP Code Intelligence Protocol", 10 | url: "https://sourcegraph.github.io/scip-java", 11 | baseUrl: baseUrl, 12 | 13 | // Used for publishing and more 14 | projectName: "scip-java", 15 | organizationName: "sourcegraph", 16 | 17 | // algolia: { 18 | // apiKey: "5791175eba35c6626d93ae96610a8ae9", 19 | // indexName: "scalamenta_mdoc" 20 | // }, 21 | 22 | // For no header links in the top nav bar -> headerLinks: [], 23 | headerLinks: [ 24 | { doc: "getting-started", label: "Docs" }, 25 | { href: repoUrl, label: "GitHub", external: true } 26 | ], 27 | 28 | // If you have users set above, you add it here: 29 | // users, 30 | 31 | /* path to images for header/footer */ 32 | headerIcon: "img/scip-java.png", 33 | footerIcon: "img/scip-java.png", 34 | favicon: "img/favicon.ico", 35 | 36 | /* colors for website */ 37 | colors: { 38 | primaryColor: "#664100", 39 | secondaryColor: "#664100" 40 | }, 41 | 42 | customDocsPath: "website/target/docs", 43 | 44 | stylesheets: [baseUrl + "css/custom.css"], 45 | 46 | 47 | usePrism: ['scala'], 48 | // This copyright info is used in /core/Footer.js and blog rss/atom feeds. 49 | copyright: `Copyright © ${new Date().getFullYear()} scip-java developers`, 50 | 51 | highlight: { 52 | // Highlight.js theme to use for syntax highlighting in code blocks 53 | theme: "github" 54 | }, 55 | 56 | /* On page navigation for the current documentation page */ 57 | onPageNav: "separate", 58 | 59 | /* Open Graph and Twitter card images */ 60 | ogImage: "img/scip-java.png", 61 | twitterImage: "img/scip-java.png", 62 | 63 | editUrl: `${repoUrl}/edit/main/docs/`, 64 | 65 | repoUrl, 66 | }; 67 | 68 | module.exports = siteConfig; 69 | -------------------------------------------------------------------------------- /website/static/css/custom.css: -------------------------------------------------------------------------------- 1 | div[data-mdoc-js] { 2 | background-color: blanchedalmond; 3 | } 4 | -------------------------------------------------------------------------------- /website/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sourcegraph/scip-java/ac4b5c7a0bcf11a531d2558d35b2169ff72695b5/website/static/img/favicon.ico -------------------------------------------------------------------------------- /website/static/img/scip-java.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sourcegraph/scip-java/ac4b5c7a0bcf11a531d2558d35b2169ff72695b5/website/static/img/scip-java.png --------------------------------------------------------------------------------