├── .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) 
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 | 
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 | *
29 | * - -Dsemanticdb.output=PATH: the file to write the updated compiler options
30 | *
- -Dsemanticdb.old-output=PATH: the file to write the original compiler options. Only used
31 | * for debugging purposes.
32 | *
- -Dsemanticdb.pluginpath=PATH: the path to the SemanticDB compiler plugin jar
33 | *
- -Dsemanticdb.sourceroot=PATH: the path to use in -Xplugin:semanticdb -sourceroot:PATH
34 | *
- -Dsemanticdb.targetroot=PATH: the path to use in -Xplugin:semanticdb -targetroot:PATH
35 | *
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 extends String, ?> 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
--------------------------------------------------------------------------------