added project structure for spring boot java language server

This commit is contained in:
Martin Lippert
2017-01-06 12:44:23 +01:00
parent 020973ec32
commit a7e6b241f4
23 changed files with 651 additions and 0 deletions

View File

@@ -12,6 +12,7 @@
<modules>
<module>commons</module>
<module>vscode-boot-properties</module>
<module>vscode-boot-java</module>
<module>vscode-manifest-yaml</module>
<module>vscode-concourse</module>
</modules>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -0,0 +1,17 @@
out
node_modules
target
*.log
*.log.*
classpath.txt
*.vsix
repo
.idea
*.iml
.DS_Store
**/.DS_Store
src/test/resources/test-projects/**/.classpath
src/test/resources/test-projects/**/.project
src/test/resources/test-projects/**/.factorypath
src/test/resources/test-projects/**/.settings/**
src/test/resources/test-projects/**/bin/**

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>vscode-boot-java</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8

View File

@@ -0,0 +1,5 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8

View File

@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@@ -0,0 +1,28 @@
// A launch configuration that compiles the extension and then opens it inside a new window
{
"version": "0.1.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
"stopOnEntry": false,
"sourceMaps": true,
"outDir": "${workspaceRoot}/out/lib",
"preLaunchTask": "npm"
},
{
"name": "Launch Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ],
"stopOnEntry": false,
"sourceMaps": true,
"outDir": "${workspaceRoot}/out/test",
"preLaunchTask": "npm"
}
]
}

View File

@@ -0,0 +1,12 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": true, // set this to true to hide the "out" folder with the compiled JS files
"node_modules": false,
"target": true
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
"typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version
}

View File

@@ -0,0 +1,30 @@
// Available variables which can be used inside of strings.
// ${workspaceRoot}: the root folder of the team
// ${file}: the current opened file
// ${fileBasename}: the current opened file's basename
// ${fileDirname}: the current opened file's dirname
// ${fileExtname}: the current opened file's extension
// ${cwd}: the current working directory of the spawned process
// A task runner that calls a custom npm script that compiles the extension.
{
"version": "0.1.0",
// we want to run npm
"command": "npm",
// the command is a shell script
"isShellCommand": true,
// show the output window only if unrecognized errors occur.
"showOutput": "silent",
// we run the custom script "compile" as defined in package.json
"args": ["run", "compile"], //, "--loglevel", "silent"],
// The tsc compiler is started in watching mode
"isWatching": true,
// use the standard tsc in watch mode problem matcher to find compile problems in the output.
"problemMatcher": "$tsc-watch"
}

View File

@@ -0,0 +1,30 @@
# IDE configs
.vscode/**
.idea/**
*.iml
javaconfig.json
classpath.txt
tsconfig.json
tsd.json
*.xml
# Logs
*.log*
# Sources
typings/**
src/**
test/**
lib/**
!lib/javaconfig.schema.json
repo/**
scripts/**
# Compiler output
out/test/**
target/**
!target/vscode-boot-properties-*.jar
# Extensions
.gitignore
**/*.map

View File

@@ -0,0 +1,73 @@
# VS Code Language Server for Spring Boot Application Properties
VSCode extension and Language Server providing support for working with Spring Boot apps in Java.
## Installation:
Currently this plugin is not distributed via vscode marketplace. You can only install
it from a .vsix file. You can download it here:
TODO: add link
To install it:
- open vscode.
- press `CTRL-SHIFT-P` and search for VSIX
- select `Extension: Install from VSIX`
## Usage:
The extension will automatically activate when you edit files with the following
name patterns:
- `*.java` => activates support for Java files
# Developer notes
## Bulding and Running
This project consists of three pieces:
- a vscode-extension which is a language-server client implemented in TypeScript.
- commons-vscode: a local npm module with some utilities implemented in TypeScript.
- a language server implemented in Java.
To build all these pieces you normally only need to run:
npm install
**However, the first time you build** it might fail trying to
find the `commons-vscode` module on npm central. Once we publish a stable
version of that module on npm central that will no longer be a problem.
Until that time, you can work around this by doing a one time manual
run of the `preinstall` script prior to running `npm install`:
./scripts/preinstall.sh
npm install
Now you can open the client-app in vscode. From the root of this project.
code .
To launch the language server in a vscode runtime, press F5.
## Debugging
To debug the language server, open `lib/Main.ts` and edit to set the
`DEBUG` option to `true`. When you laucnh the app next by pressing
`F5` it will launch with debug options being passed to the JVM.
You can then connect a 'Remote Java' Eclipse debugger on port 8000.
## Packaging as a vscode extension
First make sure the stuff is all built locally:
./scripts/preinstall.sh # only needed if this is the first build.
npm install
Then package it:
npm run vsce-package
This produces a `.vsix` file which you can install directly into vscode.

View File

@@ -0,0 +1 @@
*.js

View File

@@ -0,0 +1,37 @@
'use strict';
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as VSCode from 'vscode';
import * as Path from 'path';
import * as FS from 'fs';
import * as Net from 'net';
import * as ChildProcess from 'child_process';
import {LanguageClient, LanguageClientOptions, SettingMonitor, ServerOptions, StreamInfo} from 'vscode-languageclient';
import {TextDocument} from 'vscode';
import * as commons from 'commons-vscode';
/** Called when extension is activated */
export function activate(context: VSCode.ExtensionContext) {
let options : commons.ActivatorOptions = {
DEBUG: true,
extensionId: 'vscode-boot-java',
fatJarFile: 'target/vscode-boot-java-0.0.1-SNAPSHOT.jar',
clientOptions: {
// HACK!!! documentSelector only takes string|string[] where string is language id, but DocumentFilter object is passed instead
// Reasons:
// 1. documentSelector is just passed over to functions like #registerHoverProvider(documentSelector, ...) that take documentSelector
// parameter in string | DocumentFilter | string[] | DocumentFilter[] format
// 2. Combination of non string|string[] documentSelector parameter and synchronize.textDocumentFilter function makes doc synchronization
// events pass on to Language Server only for documents for which function passed via textDocumentFilter property return true
// TODO: Remove <any> cast ones https://github.com/Microsoft/vscode-languageserver-node/issues/9 is resolved
documentSelector: ['java'],
synchronize: {
configurationSection: 'vscode-boot-java'
}
}
};
commons.activate(options, context);
}

View File

@@ -0,0 +1,47 @@
{
"name": "vscode-boot-java",
"displayName": "Spring Boot Java Support",
"description": "Provides validation, content assist, and more working with Spring Boot applications Java code",
"icon": "spring-boot-logo.png",
"version": "0.0.1",
"publisher": "Pivotal",
"repository": {
"type": "git",
"url": "https://github.com/spring-projects/sts4.git"
},
"license": "EPL-1.0",
"engines": {
"npm": "^3.0.0",
"vscode": "^1.5.0"
},
"categories": [
"Languages",
"Linters"
],
"keywords": [
"java", "spring-boot"
],
"activationEvents": [
"onLanguage:ini",
"onLanguage:java"
],
"main": "./out/lib/Main",
"scripts": {
"prepublish": "tsc -p .",
"clean": "rm -fr node_modules out *.vsix",
"compile": "tsc -watch -p ./",
"preinstall": "./scripts/preinstall.sh",
"postinstall": "node ./node_modules/vscode/bin/install",
"vsce-package": "vsce package"
},
"dependencies": {
"vscode-languageclient": "2.5.x",
"commons-vscode": "^0.0.1"
},
"devDependencies": {
"vsce": "^1.17.0",
"typescript": "^2.0.x",
"@types/node": "^6.0.40",
"vscode": "^1.0.0"
}
}

View File

@@ -0,0 +1,94 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>vscode-boot-java</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../commons/pom.xml</relativePath>
</parent>
<repositories>
<!-- Sonatype snapshots repository -->
<repository>
<id>oss-sonatype</id>
<name>oss-sonatype</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>distribution-repository</id>
<name>Temporary Staging Repository</name>
<url>file://${basedir}/dist</url>
</repository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-maven</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-language-server</artifactId>
<version>${project.version}</version>
</dependency>
<!-- Test harness -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>language-server-test-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Set source 1.8 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- Configure fat jar -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.1.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Ignore test classes from test projects -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<excludes>
<exclude>test-projects/**</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,5 @@
#!/bin/bash
set -e
(cd ../commons-vscode ; npm install)
npm install ../commons-vscode
../mvnw -U -f ../pom.xml -pl vscode-boot-java -am clean install

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2016 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java;
import org.eclipse.lsp4j.CompletionOptions;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.springframework.ide.vscode.boot.java.completions.BootJavaCompletionEngine;
import org.springframework.ide.vscode.boot.java.completions.BootJavaReconcileEngine;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
import org.springframework.ide.vscode.commons.languageserver.java.DefaultJavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.java.IJavaProjectFinderStrategy;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
import org.springframework.ide.vscode.commons.maven.JavaProjectWithClasspathFileFinderStrategy;
import org.springframework.ide.vscode.commons.maven.MavenProjectFinderStrategy;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
/**
* Language Server for Spring Boot Application Properties files
*
* @author Martin Lippert
*/
public class BootJavaLanguageServer extends SimpleLanguageServer {
public static final JavaProjectFinder DEFAULT_PROJECT_FINDER = new DefaultJavaProjectFinder(new IJavaProjectFinderStrategy[] {
new MavenProjectFinderStrategy(),
new JavaProjectWithClasspathFileFinderStrategy()
});
private final JavaProjectFinder javaProjectFinder;
private final VscodeCompletionEngineAdapter completionEngine;
public BootJavaLanguageServer(JavaProjectFinder javaProjectFinder) {
this.javaProjectFinder = javaProjectFinder;
SimpleTextDocumentService documents = getTextDocumentService();
IReconcileEngine reconcileEngine = new BootJavaReconcileEngine();
documents.onDidChangeContent(params -> {
TextDocument doc = params.getDocument();
validateWith(doc, reconcileEngine);
});
ICompletionEngine bootCompletionEngine = new BootJavaCompletionEngine();
completionEngine = new VscodeCompletionEngineAdapter(this, bootCompletionEngine);
completionEngine.setMaxCompletionsNumber(100);
documents.onCompletion(completionEngine::getCompletions);
documents.onCompletionResolve(completionEngine::resolveCompletion);
}
public void setMaxCompletionsNumber(int number) {
completionEngine.setMaxCompletionsNumber(number);
}
@Override
protected ServerCapabilities getServerCapabilities() {
ServerCapabilities c = new ServerCapabilities();
c.setTextDocumentSync(TextDocumentSyncKind.Incremental);
CompletionOptions completionProvider = new CompletionOptions();
completionProvider.setResolveProvider(false);
c.setCompletionProvider(completionProvider);
return c;
}
}

View File

@@ -0,0 +1,34 @@
/*******************************************************************************
* Copyright (c) 2016 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java;
import java.io.IOException;
import org.springframework.ide.vscode.commons.languageserver.LaunguageServerApp;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
/**
* Starts up Language Server process
*
* @author Martin Lippert
*/
public class Main {
public static void main(String[] args) throws IOException {
LaunguageServerApp.start(() -> {
JavaProjectFinder javaProjectFinder = BootJavaLanguageServer.DEFAULT_PROJECT_FINDER;
SimpleLanguageServer server = new BootJavaLanguageServer(javaProjectFinder);
return server;
});
}
}

View File

@@ -0,0 +1,62 @@
package org.springframework.ide.vscode.boot.java.completions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.lsp4j.CompletionItemKind;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.commons.util.Renderable;
import org.springframework.ide.vscode.commons.util.Renderables;
import org.springframework.ide.vscode.commons.util.text.IDocument;
public class BootJavaCompletionEngine implements ICompletionEngine {
@Override
public Collection<ICompletionProposal> getCompletions(IDocument document, int offset) throws Exception {
List<ICompletionProposal> completions = new ArrayList<>();
ICompletionProposal proposal = new ICompletionProposal() {
@Override
public DocumentEdits getTextEdit() {
DocumentEdits edits = new DocumentEdits(document);
edits.insert(0, "my noew java code from spring boot completions!!!");
return edits;
}
@Override
public String getLabel() {
return "Do a great Spring Boot Java Code completion";
}
@Override
public CompletionItemKind getKind() {
return CompletionItemKind.Text;
}
@Override
public Renderable getDocumentation() {
return Renderables.text("this describes the Boot Java completion in more detail");
}
@Override
public String getDetail() {
return "and here are the details";
}
@Override
public ICompletionProposal deemphasize() {
return null;
}
};
completions.add(proposal);
return completions;
}
}

View File

@@ -0,0 +1,13 @@
package org.springframework.ide.vscode.boot.java.completions;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
import org.springframework.ide.vscode.commons.util.text.IDocument;
public class BootJavaReconcileEngine implements IReconcileEngine {
@Override
public void reconcile(IDocument doc, IProblemCollector problemCollector) {
}
}

View File

@@ -0,0 +1,21 @@
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"target": "es6",
"lib": [
"es6"
],
"declaration": true,
"outDir": "out",
"sourceMap": true,
"rootDir": "."
},
"include": [
"typings/*.d.ts",
"lib/**/*.ts"
],
"exclude": [
"node_modules"
]
}