Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VSC] Accounts and contacts (1/5) #955

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ buildSrc/.gradle
/stf/.project
/stf.test/.project
.DS_Store
/.gradle/
docs/_site
docs/Gemfile.lock
.gradle/
/build/
**/.settings/org.eclipse.buildship.core.prefs
.classpath
Expand All @@ -58,3 +60,14 @@ buildSrc/.gradle
# LSP
lsp/.classpath
lsp/build

# VS Code
vscode*/.classpath
vscode*/.project
vscode*/build
vscode*/package-lock.json
vscode*/.vscode
*.vscode
*.code-workspace
*.vscodeignore
dist/
13 changes: 13 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ tasks {
from(project(":saros.server").tasks.findByName("jar"))
into("build/distribution/server")
}

register("sarosLsp", Copy::class) {
dependsOn(
":saros.core:test",
Expand All @@ -277,6 +278,18 @@ tasks {
from(project(":saros.lsp").tasks.findByName("jar"))
into("build/distribution/lsp")
}

register("sarosVSCode", Copy::class) {
dependsOn(
"sarosLsp",
":saros.vscode:packageExtension"
)
group = "Build"
description = "Builds and tests all modules required by the Saros VS Code Extension"

from("vscode/vsix")
into("build/distribution/vscode")
}

register("sarosIntellij", Copy::class) {
dependsOn(
Expand Down
46 changes: 44 additions & 2 deletions docs/contribute/development-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,45 @@ This is necessary in order to allow IntelliJ to execute all build and test actio
* Click on `Open`
* Select the repository root as project root and click `OK`

## Develop with VS Code

When developing with VS Code you rely on your installed extensions. When opening a file with an extension that has currently no support VS Code will ask for installing necessary plugins. When being asked either install what is suggested or install by your own preference.

### Developing the VS Code Extension

When developing the extension you have two ways to start the debugger:

#### Using a launch configuration (preferred)

Create the `launch.json` in your `.vscode` directory of the folder you opened with vscode. When using a `workspace` you have to reference your launch file there also. The `launch.json` has the following content:

```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "gradle: prepareVSCode"
}
]
}
```

#### Using gradle

Using gradle tasks directly has the benefits of starting multiple instances of the `VS Code Extension Host` which is useful for testing multiple at once. Just open the available tasks (usually `CTRL+SHIFT+T`) and run `runVSCode` in order to start the extension in an `Extension Host`. When debugging is needed just hit `F5` and choose the NodeJs debugger and attach to the desired process.

To make it more comfortable a keybinding can be assigned to that task (`keybindings.json`) or the launch configuration of the NodeJs debugger can be saved (`launch.json`) in order to attach via `F5`.

## Develop Without an IDE

If you prefer to develop with a text editor (like Vim or Emacs) you can build and test
Expand All @@ -97,14 +136,17 @@ The following tasks are used to build and test the different Saros components:
* `sarosEclipse` - Triggers the build and test of the Saros Eclipse Plugin
* `sarosIntellij` - Triggers the build and test of the Saros IntelliJ Plugin
* `sarosServer` - Triggers the build and test of the Saros Server
* `sarosLsp` - Triggers the build and test of the Saros Language Server
* `sarosVSCode` - Triggers the build and test of the Saros VS Code Extension
* `prepareEclipse` - Executes all tasks which are required before developing in Eclipse
* `runIde` - Starts a IntelliJ IDE containing the Saros Plugin. The IDE version depends on the value of `INTELLIJ_HOME` or the `intellijVersion` specified in the build file of the IntelliJ package.
* `runVSCode` - Starts an VS Code (Extension Host) with the Saros Extension. Use the node debugger to attach to the process for debugging.

In order to build the whole project without using existing build artifacts simply call `./gradlew cleanAll sarosEclipse sarosIntellij sarosServer`.
In order to build the whole project without using existing build artifacts simply call `./gradlew cleanAll sarosEclipse sarosIntellij sarosServer sarosVSCode`.

Gradle checks whether the component specific sources are changed. Therefore a task become a NOP if nothing changed and the build results still exist.
If you want to force Gradle to re-execute the tasks, you have to call `./gradlew --rerun-tasks <task>...` or call the `cleanAll` task before other tasks.
The final build results are copied into the directory `<repository root>/build/distribute/(eclipse|intellij)`.
The final build results are copied into the directory `<repository root>/build/distribute/(eclipse|intellij|vscode|lsp)`.

### Formatting via Standalone Google Java Formatter

Expand Down
17 changes: 11 additions & 6 deletions lsp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ configurations {

dependencies {
compile(project(":saros.core"))
compile(project(":saros.server"))
compile("org.apache.commons:commons-collections4:4.2")
compile("org.eclipse.lsp4j:org.eclipse.lsp4j:0.8.1")
compile("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.8.1")
compile("org.eclipse.lsp4j:org.eclipse.lsp4j:0.9.0")
compile("org.eclipse.lsp4j:org.eclipse.lsp4j.jsonrpc:0.9.0")
compile("info.picocli:picocli:4.2.0")
}

sourceSets {
Expand All @@ -37,12 +37,17 @@ tasks.jar {
))
}
from(
configurations.compile.get().map { if (it.isDirectory) it else zipTree(it) }
configurations.compile.get().map {if (it.isDirectory) it else zipTree(it) }
)

from("src/log4j.properties")
from(rootProject.file("saros_log4j2.xml"))
from(rootProject.file("log4j2.xml"))
exclude("**/*.jar")

// Exclude files that prevent the jar from starting
exclude("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA")

// Exclude ambigious Log4j2Plugins.dat resulting from bug LOG4J2-954
// see https://issues.apache.org/jira/browse/LOG4J2-954
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
86 changes: 63 additions & 23 deletions lsp/src/saros/lsp/SarosLanguageServer.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,51 @@
package saros.lsp;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import org.apache.log4j.Logger;
import java.util.function.Consumer;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.services.TextDocumentService;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.eclipse.lsp4j.services.WorkspaceService;
import saros.lsp.extensions.ISarosLanguageServer;
import saros.lsp.extensions.client.ISarosLanguageClient;
import saros.lsp.extensions.client.ISarosLanguageClientAware;
import saros.lsp.extensions.server.account.AccountService;
import saros.lsp.extensions.server.ISarosLanguageServer;
import saros.lsp.extensions.server.account.IAccountService;
import saros.lsp.service.DocumentServiceStub;
import saros.lsp.service.WorkspaceServiceStub;
import saros.lsp.extensions.server.connection.IConnectionService;
import saros.lsp.extensions.server.contact.IContactService;
import saros.lsp.extensions.server.document.IDocumentService;

/** Implementation of the Saros language server. */
// TODO: Remove SuppressWarning after Server and Client interaction is on master branch
@SuppressWarnings({"PMD.UnusedPrivateField"})
public class SarosLanguageServer implements ISarosLanguageServer, ISarosLanguageClientAware {
/** Implmenentation of {@link ISarosLanguageServer}. */
public class SarosLanguageServer implements ISarosLanguageServer {

private static final Logger log = Logger.getLogger(SarosLanguageServer.class);
private IAccountService accountService;

private ISarosLanguageClient languageClient;
private IContactService contactService;

private IDocumentService documentService;

private WorkspaceService workspaceService;

private IConnectionService connectionService;

public SarosLanguageServer(
IAccountService accountService,
IContactService contactService,
IDocumentService documentService,
IConnectionService connectionService,
WorkspaceService workspaceService) {
this.accountService = accountService;
this.contactService = contactService;
this.documentService = documentService;
this.connectionService = connectionService;
this.workspaceService = workspaceService;
}

@Override
public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you return a Future when it is always completed when this method return ?


this.initializeListeners.forEach(listener -> listener.accept(params));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Either name it consumer or visitor. A listener do not accept anything.


return CompletableFuture.completedFuture(new InitializeResult(this.createCapabilities()));
}

Expand All @@ -46,37 +66,57 @@ public CompletableFuture<InitializeResult> initialize(InitializeParams params) {
private ServerCapabilities createCapabilities() {
ServerCapabilities capabilities = new ServerCapabilities();

capabilities.setExperimental(true);
capabilities.setTextDocumentSync(TextDocumentSyncKind.Incremental);

return capabilities;
}

@Override
public CompletableFuture<Object> shutdown() {
log.info("shutdown");
return CompletableFuture.completedFuture(null);
}

@Override
public void exit() {
log.info("exit");
this.exitListeners.forEach(listener -> listener.run());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

callback or hook is the correct naming instead of listener, especially when you call run

}

private List<Runnable> exitListeners = new ArrayList<>();
private List<Consumer<InitializeParams>> initializeListeners = new ArrayList<>();

@Override
public TextDocumentService getTextDocumentService() {
return new DocumentServiceStub();
public void onInitialize(Consumer<InitializeParams> consumer) {
this.initializeListeners.add(consumer);
}

@Override
public WorkspaceService getWorkspaceService() {
return new WorkspaceServiceStub();
public void onExit(Runnable runnable) {
this.exitListeners.add(runnable);
}

@Override
public void connect(ISarosLanguageClient client) {
this.languageClient = client;
public IDocumentService getTextDocumentService() {
return this.documentService;
}

@Override
public WorkspaceService getWorkspaceService() {
return this.workspaceService;
}

@Override
public IAccountService getSarosAccountService() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smurf

return new AccountService();
return this.accountService;
}

@Override
public IContactService getSarosContactService() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smurf

return this.contactService;
}

@Override
public IConnectionService getSarosConnectionService() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

smurf

return this.connectionService;
}
}
Loading