diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ccda1dddc8..17aa9ef0250 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,9 +12,15 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macOS-latest] + java-version: + - "adopt@1.11" + - "adopt@1.8" + - "openjdk@1.11" steps: - uses: actions/checkout@v1 - uses: olafurpg/setup-scala@v7 + with: + java-version: ${{ matrix.java-version }} - name: Run unit tests run: | bin/test.sh unit/test diff --git a/metals/src/main/scala/scala/meta/internal/worksheets/WorkspaceEditWorksheetPublisher.scala b/metals/src/main/scala/scala/meta/internal/worksheets/WorkspaceEditWorksheetPublisher.scala index 943f1629c21..c78ff29344f 100644 --- a/metals/src/main/scala/scala/meta/internal/worksheets/WorkspaceEditWorksheetPublisher.scala +++ b/metals/src/main/scala/scala/meta/internal/worksheets/WorkspaceEditWorksheetPublisher.scala @@ -143,7 +143,7 @@ class WorkspaceEditWorksheetPublisher(buffers: Buffers) private def updateWithEdits(text: String, edits: List[TextEdit]): String = { val editsMap = edits.map(e => e.getRange().getStart().getLine() -> e).toMap - text.lines.zipWithIndex + text.linesIterator.zipWithIndex .map { case (line, i) => editsMap.get(i) match { diff --git a/tests/unit/src/main/scala/tests/JVMVersion.scala b/tests/unit/src/main/scala/tests/JVMVersion.scala new file mode 100644 index 00000000000..a561df26fe8 --- /dev/null +++ b/tests/unit/src/main/scala/tests/JVMVersion.scala @@ -0,0 +1,87 @@ +package tests + +import scala.util._ +import scala.util.matching._ + +/** ADT used to model the current version of the runtime JVM. + * + * It is needed to know the current version for several of the test cases as + * there are some changes to the classpath between different JVM versions. + * + * For example, on JDK > 8 several standard jar files are now stored as java + * modules and will now longer show up as standalone jars, + * e.g. `charsets.jar`. + */ +sealed trait JVMVersion extends Product with Serializable { + def value: String +} + +object JVMVersion { + + /** The value of the System property `java.version` used to determine the + * JVM version. It is an `Option` as system values may be `null`. + */ + val javaVmVersion: Option[String] = + Option(System.getProperty("java.version")) // null check + + /** A regular expression used to parse the value of `java.version` into + * components. This makes it easy to discriminate on a particular major + * version number. + */ + val numericJVMVersionRegex: Regex = + raw"""(\d+)\.(\d+)\.(\d+)(.*)""".r + + /** ADT constructor for a numeric JVM version. + * + * This is the canonical representation we expect, though strictly + * speaking, it is not a requirement that the JVM version be numeric. + */ + final case class NumericJVMVersion( + major: Long, + override final val value: String + ) extends JVMVersion + + /** ADT constructor for a non-numeric JVM version. + * + * This is the exceptional case, as we normally expect the JVM version to + * be numeric. + */ + final case class NonNumericJVMVersion(override final val value: String) + extends JVMVersion + + /** The currently running JVMVersion value. + * + * @note this value will be `None` if the system property `java.version` + * is `null.` + * + * The expected way to use this is to pattern match on the result to + * execute specific code for some specific JVM version. + * + * {{{ + * jvmVersion match { + * case Some(NumericJVMVersion(major, _,)) if major > 8L => // Do something special for JDK > 8 + * case _ => // Do something else + * } + * }}} + */ + val jvmVersion: Option[JVMVersion] = + this.javaVmVersion.map((version: String) => + version match { + case numericJVMVersionRegex(aS, bS, cS, suffix) => + ( + for { + a <- Try(aS.toLong) + b <- Try(bS.toLong) + } yield + if (a == 1L) { + // Then this is an old style version number, e.g. 1.8.0 + NumericJVMVersion(b, version) + } else { + NumericJVMVersion(a, version) + } + ).getOrElse(NonNumericJVMVersion(version)) // if the regex is properly defined, this branch should never execute. + case otherwise => + NonNumericJVMVersion(otherwise) + } + ) +} diff --git a/tests/unit/src/test/scala/tests/TreeViewLspSuite.scala b/tests/unit/src/test/scala/tests/TreeViewLspSuite.scala index 78aa4db5a5f..44d2e702127 100644 --- a/tests/unit/src/test/scala/tests/TreeViewLspSuite.scala +++ b/tests/unit/src/test/scala/tests/TreeViewLspSuite.scala @@ -1,9 +1,50 @@ package tests +import scala.collection.SortedSet import scala.meta.internal.tvp.TreeViewProvider object TreeViewLspSuite extends BaseLspSuite("tree-view") { + /** The libraries we expect to find for tests in this file. + * + * @note this value changes depending on the JVM version in use as some JAR + * files have moved to become modules on JVM > 8. + */ + val expectedLibraries: SortedSet[String] = { + lazy val jdk8Libraries = SortedSet( + "charsets", + "jce", + "jsse", + "resources", + "rt" + ) + + val otherLibraries = SortedSet( + "animal-sniffer-annotations", "cats-core_2.12", "cats-kernel_2.12", + "cats-macros_2.12", "checker-qual", "circe-core_2.12", + "circe-numbers_2.12", "error_prone_annotations", "failureaccess", "gson", + "guava", "j2objc-annotations", "jsr305", "listenablefuture", + "machinist_2.12", "org.eclipse.lsp4j", "org.eclipse.lsp4j.generator", + "org.eclipse.lsp4j.jsonrpc", "org.eclipse.xtend.lib", + "org.eclipse.xtend.lib.macro", "org.eclipse.xtext.xbase.lib", + "scala-library", "scala-reflect", "sourcecode_2.12" + ) + JVMVersion.jvmVersion match { + case Some(JVMVersion.NumericJVMVersion(major, _)) if major <= 8L => + otherLibraries ++ jdk8Libraries + case _ => + otherLibraries + } + } + + lazy val expectedLibrariesString: String = + this.expectedLibraries.toVector + .map((s: String) => s"${s}.jar -") + .mkString("\n") + + lazy val expectedLibrariesCount: Int = + this.expectedLibraries.size + testAsync("projects") { cleanWorkspace() for { @@ -100,35 +141,7 @@ object TreeViewLspSuite extends BaseLspSuite("tree-view") { ) server.assertTreeViewChildren( s"libraries:", - """|animal-sniffer-annotations.jar - - |cats-core_2.12.jar - - |cats-kernel_2.12.jar - - |cats-macros_2.12.jar - - |charsets.jar - - |checker-qual.jar - - |circe-core_2.12.jar - - |circe-numbers_2.12.jar - - |error_prone_annotations.jar - - |failureaccess.jar - - |gson.jar - - |guava.jar - - |j2objc-annotations.jar - - |jce.jar - - |jsr305.jar - - |jsse.jar - - |listenablefuture.jar - - |machinist_2.12.jar - - |org.eclipse.lsp4j.jar - - |org.eclipse.lsp4j.generator.jar - - |org.eclipse.lsp4j.jsonrpc.jar - - |org.eclipse.xtend.lib.jar - - |org.eclipse.xtend.lib.macro.jar - - |org.eclipse.xtext.xbase.lib.jar - - |resources.jar - - |rt.jar - - |scala-library.jar - - |scala-reflect.jar - - |sourcecode_2.12.jar -""".stripMargin + expectedLibrariesString ) server.assertTreeViewChildren( s"libraries:${server.jar("scala-library")}!/scala/Some#", @@ -182,51 +195,51 @@ object TreeViewLspSuite extends BaseLspSuite("tree-view") { !label.contains("sourcecode") } ), - """|root - | Import build command - | Connect to build server command - | Projects (0) - | Libraries (29) - | Libraries (29) - | sourcecode_2.12-0.1.7.jar - | sourcecode_2.12-0.1.7.jar - | sourcecode/ - | sourcecode/ - | Args class - | Args object - | ArgsMacros trait - | Compat object - | Enclosing class - | Enclosing object - | EnclosingMachineMacros trait - | EnclosingMacros trait - | File class - | File object - | FileMacros trait - | FullName class - | FullName object - | FullNameMachineMacros trait - | FullNameMacros trait - | Line class - | Line object - | LineMacros trait - | Macros object - | Name class - | Name object - | NameMachineMacros trait - | NameMacros trait - | Pkg class - | Pkg object - | PkgMacros trait - | SourceCompanion class - | SourceValue class - | Text class - | Text object - | TextMacros trait - | Util object - | File class - | value val - |""".stripMargin + s"""|root + | Import build command + | Connect to build server command + | Projects (0) + | Libraries (${expectedLibrariesCount}) + | Libraries (${expectedLibrariesCount}) + | sourcecode_2.12-0.1.7.jar + | sourcecode_2.12-0.1.7.jar + | sourcecode/ + | sourcecode/ + | Args class + | Args object + | ArgsMacros trait + | Compat object + | Enclosing class + | Enclosing object + | EnclosingMachineMacros trait + | EnclosingMacros trait + | File class + | File object + | FileMacros trait + | FullName class + | FullName object + | FullNameMachineMacros trait + | FullNameMacros trait + | Line class + | Line object + | LineMacros trait + | Macros object + | Name class + | Name object + | NameMachineMacros trait + | NameMacros trait + | Pkg class + | Pkg object + | PkgMacros trait + | SourceCompanion class + | SourceValue class + | Text class + | Text object + | TextMacros trait + | Util object + | File class + | value val + |""".stripMargin ) assertNoDiff( server.treeViewReveal( @@ -237,209 +250,209 @@ object TreeViewLspSuite extends BaseLspSuite("tree-view") { !label.contains("lsp4j") } ), - """|root - | Import build command - | Connect to build server command - | Projects (0) - | Libraries (29) - | Libraries (29) - | org.eclipse.lsp4j-0.5.0.jar - | org.eclipse.lsp4j.generator-0.5.0.jar - | org.eclipse.lsp4j.jsonrpc-0.5.0.jar - | org.eclipse.lsp4j-0.5.0.jar - | org/ - | org/ - | eclipse/ - | eclipse/ - | lsp4j/ - | lsp4j/ - | adapters/ - | launch/ - | services/ - | util/ - | ApplyWorkspaceEditParams class - | ApplyWorkspaceEditResponse class - | ClientCapabilities class - | CodeAction class - | CodeActionCapabilities class - | CodeActionContext class - | CodeActionKind class - | CodeActionKindCapabilities class - | CodeActionLiteralSupportCapabilities class - | CodeActionParams class - | CodeLens class - | CodeLensCapabilities class - | CodeLensOptions class - | CodeLensParams class - | CodeLensRegistrationOptions class - | Color class - | ColorInformation class - | ColorPresentation class - | ColorPresentationParams class - | ColorProviderCapabilities class - | ColorProviderOptions class - | ColoringInformation class - | ColoringParams class - | ColoringStyle class - | Command class - | CompletionCapabilities class - | CompletionContext class - | CompletionItem class - | CompletionItemCapabilities class - | CompletionItemKind class - | CompletionItemKindCapabilities class - | CompletionList class - | CompletionOptions class - | CompletionParams class - | CompletionRegistrationOptions class - | CompletionTriggerKind class - | ConfigurationItem class - | ConfigurationParams class - | DefinitionCapabilities class - | Diagnostic class - | DiagnosticRelatedInformation class - | DiagnosticSeverity class - | DidChangeConfigurationCapabilities class - | DidChangeConfigurationParams class - | DidChangeTextDocumentParams class - | DidChangeWatchedFilesCapabilities class - | DidChangeWatchedFilesParams class - | DidChangeWatchedFilesRegistrationOptions class - | DidChangeWorkspaceFoldersParams class - | DidCloseTextDocumentParams class - | DidOpenTextDocumentParams class - | DidSaveTextDocumentParams class - | DocumentColorParams class - | DocumentFilter class - | DocumentFormattingParams class - | DocumentHighlight class - | DocumentHighlightCapabilities class - | DocumentHighlightKind class - | DocumentLink class - | DocumentLinkCapabilities class - | DocumentLinkOptions class - | DocumentLinkParams class - | DocumentLinkRegistrationOptions class - | DocumentOnTypeFormattingOptions class - | DocumentOnTypeFormattingParams class - | DocumentOnTypeFormattingRegistrationOptions class - | DocumentRangeFormattingParams class - | DocumentSymbol class - | DocumentSymbolCapabilities class - | DocumentSymbolParams class - | DynamicRegistrationCapabilities class - | ExecuteCommandCapabilities class - | ExecuteCommandOptions class - | ExecuteCommandParams class - | ExecuteCommandRegistrationOptions class - | FileChangeType class - | FileEvent class - | FileSystemWatcher class - | FoldingRange class - | FoldingRangeCapabilities class - | FoldingRangeKind class - | FoldingRangeProviderOptions class - | FoldingRangeRequestParams class - | FormattingCapabilities class - | FormattingOptions class - | Hover class - | HoverCapabilities class - | ImplementationCapabilities class - | InitializeError class - | InitializeErrorCode class - | InitializeParams class - | InitializeResult class - | InitializedParams class - | InsertTextFormat class - | Location class - | MarkedString class - | MarkupContent class - | MarkupKind class - | MessageActionItem class - | MessageParams class - | MessageType class - | OnTypeFormattingCapabilities class - | ParameterInformation class - | Position class - | PublishDiagnosticsCapabilities class - | PublishDiagnosticsParams class - | Range class - | RangeFormattingCapabilities class - | ReferenceContext class - | ReferenceParams class - | ReferencesCapabilities class - | Registration class - | RegistrationParams class - | RenameCapabilities class - | RenameParams class - | ResourceChange class - | ResponseErrorCode class - | SaveOptions class - | SemanticHighlightingCapabilities class - | SemanticHighlightingInformation class - | SemanticHighlightingParams class - | SemanticHighlightingServerCapabilities class - | ServerCapabilities class - | ShowMessageRequestParams class - | SignatureHelp class - | SignatureHelpCapabilities class - | SignatureHelpOptions class - | SignatureHelpRegistrationOptions class - | SignatureInformation class - | SignatureInformationCapabilities class - | StaticRegistrationOptions class - | SymbolCapabilities class - | SymbolInformation class - | SymbolKind class - | SymbolKindCapabilities class - | SynchronizationCapabilities class - | TextDocumentChangeRegistrationOptions class - | TextDocumentClientCapabilities class - | TextDocumentContentChangeEvent class - | TextDocumentEdit class - | TextDocumentIdentifier class - | TextDocumentItem class - | TextDocumentPositionParams class - | TextDocumentRegistrationOptions class - | TextDocumentSaveReason class - | TextDocumentSaveRegistrationOptions class - | TextDocumentSyncKind class - | TextDocumentSyncOptions class - | TextEdit class - | TypeDefinitionCapabilities class - | Unregistration class - | UnregistrationParams class - | VersionedTextDocumentIdentifier class - | WatchKind class - | WillSaveTextDocumentParams class - | WorkspaceClientCapabilities class - | WorkspaceEdit class - | WorkspaceEditCapabilities class - | WorkspaceFolder class - | WorkspaceFoldersChangeEvent class - | WorkspaceFoldersOptions class - | WorkspaceServerCapabilities class - | WorkspaceSymbolParams class - | services/ - | LanguageClient class - | LanguageClientAware class - | LanguageClientExtensions class - | LanguageServer class - | TextDocumentService class - | WorkspaceService class - | LanguageClient class - | applyEdit() method - | registerCapability() method - | unregisterCapability() method - | telemetryEvent() method - | publishDiagnostics() method - | showMessage() method - | showMessageRequest() method - | logMessage() method - | workspaceFolders() method - | configuration() method - | semanticHighlighting() method - |""".stripMargin + s"""|root + | Import build command + | Connect to build server command + | Projects (0) + | Libraries (${expectedLibrariesCount}) + | Libraries (${expectedLibrariesCount}) + | org.eclipse.lsp4j-0.5.0.jar + | org.eclipse.lsp4j.generator-0.5.0.jar + | org.eclipse.lsp4j.jsonrpc-0.5.0.jar + | org.eclipse.lsp4j-0.5.0.jar + | org/ + | org/ + | eclipse/ + | eclipse/ + | lsp4j/ + | lsp4j/ + | adapters/ + | launch/ + | services/ + | util/ + | ApplyWorkspaceEditParams class + | ApplyWorkspaceEditResponse class + | ClientCapabilities class + | CodeAction class + | CodeActionCapabilities class + | CodeActionContext class + | CodeActionKind class + | CodeActionKindCapabilities class + | CodeActionLiteralSupportCapabilities class + | CodeActionParams class + | CodeLens class + | CodeLensCapabilities class + | CodeLensOptions class + | CodeLensParams class + | CodeLensRegistrationOptions class + | Color class + | ColorInformation class + | ColorPresentation class + | ColorPresentationParams class + | ColorProviderCapabilities class + | ColorProviderOptions class + | ColoringInformation class + | ColoringParams class + | ColoringStyle class + | Command class + | CompletionCapabilities class + | CompletionContext class + | CompletionItem class + | CompletionItemCapabilities class + | CompletionItemKind class + | CompletionItemKindCapabilities class + | CompletionList class + | CompletionOptions class + | CompletionParams class + | CompletionRegistrationOptions class + | CompletionTriggerKind class + | ConfigurationItem class + | ConfigurationParams class + | DefinitionCapabilities class + | Diagnostic class + | DiagnosticRelatedInformation class + | DiagnosticSeverity class + | DidChangeConfigurationCapabilities class + | DidChangeConfigurationParams class + | DidChangeTextDocumentParams class + | DidChangeWatchedFilesCapabilities class + | DidChangeWatchedFilesParams class + | DidChangeWatchedFilesRegistrationOptions class + | DidChangeWorkspaceFoldersParams class + | DidCloseTextDocumentParams class + | DidOpenTextDocumentParams class + | DidSaveTextDocumentParams class + | DocumentColorParams class + | DocumentFilter class + | DocumentFormattingParams class + | DocumentHighlight class + | DocumentHighlightCapabilities class + | DocumentHighlightKind class + | DocumentLink class + | DocumentLinkCapabilities class + | DocumentLinkOptions class + | DocumentLinkParams class + | DocumentLinkRegistrationOptions class + | DocumentOnTypeFormattingOptions class + | DocumentOnTypeFormattingParams class + | DocumentOnTypeFormattingRegistrationOptions class + | DocumentRangeFormattingParams class + | DocumentSymbol class + | DocumentSymbolCapabilities class + | DocumentSymbolParams class + | DynamicRegistrationCapabilities class + | ExecuteCommandCapabilities class + | ExecuteCommandOptions class + | ExecuteCommandParams class + | ExecuteCommandRegistrationOptions class + | FileChangeType class + | FileEvent class + | FileSystemWatcher class + | FoldingRange class + | FoldingRangeCapabilities class + | FoldingRangeKind class + | FoldingRangeProviderOptions class + | FoldingRangeRequestParams class + | FormattingCapabilities class + | FormattingOptions class + | Hover class + | HoverCapabilities class + | ImplementationCapabilities class + | InitializeError class + | InitializeErrorCode class + | InitializeParams class + | InitializeResult class + | InitializedParams class + | InsertTextFormat class + | Location class + | MarkedString class + | MarkupContent class + | MarkupKind class + | MessageActionItem class + | MessageParams class + | MessageType class + | OnTypeFormattingCapabilities class + | ParameterInformation class + | Position class + | PublishDiagnosticsCapabilities class + | PublishDiagnosticsParams class + | Range class + | RangeFormattingCapabilities class + | ReferenceContext class + | ReferenceParams class + | ReferencesCapabilities class + | Registration class + | RegistrationParams class + | RenameCapabilities class + | RenameParams class + | ResourceChange class + | ResponseErrorCode class + | SaveOptions class + | SemanticHighlightingCapabilities class + | SemanticHighlightingInformation class + | SemanticHighlightingParams class + | SemanticHighlightingServerCapabilities class + | ServerCapabilities class + | ShowMessageRequestParams class + | SignatureHelp class + | SignatureHelpCapabilities class + | SignatureHelpOptions class + | SignatureHelpRegistrationOptions class + | SignatureInformation class + | SignatureInformationCapabilities class + | StaticRegistrationOptions class + | SymbolCapabilities class + | SymbolInformation class + | SymbolKind class + | SymbolKindCapabilities class + | SynchronizationCapabilities class + | TextDocumentChangeRegistrationOptions class + | TextDocumentClientCapabilities class + | TextDocumentContentChangeEvent class + | TextDocumentEdit class + | TextDocumentIdentifier class + | TextDocumentItem class + | TextDocumentPositionParams class + | TextDocumentRegistrationOptions class + | TextDocumentSaveReason class + | TextDocumentSaveRegistrationOptions class + | TextDocumentSyncKind class + | TextDocumentSyncOptions class + | TextEdit class + | TypeDefinitionCapabilities class + | Unregistration class + | UnregistrationParams class + | VersionedTextDocumentIdentifier class + | WatchKind class + | WillSaveTextDocumentParams class + | WorkspaceClientCapabilities class + | WorkspaceEdit class + | WorkspaceEditCapabilities class + | WorkspaceFolder class + | WorkspaceFoldersChangeEvent class + | WorkspaceFoldersOptions class + | WorkspaceServerCapabilities class + | WorkspaceSymbolParams class + | services/ + | LanguageClient class + | LanguageClientAware class + | LanguageClientExtensions class + | LanguageServer class + | TextDocumentService class + | WorkspaceService class + | LanguageClient class + | applyEdit() method + | registerCapability() method + | unregisterCapability() method + | telemetryEvent() method + | publishDiagnostics() method + | showMessage() method + | showMessageRequest() method + | logMessage() method + | workspaceFolders() method + | configuration() method + | semanticHighlighting() method + |""".stripMargin ) } } yield ()