This commit is contained in:
BoykoAlex
2017-07-21 13:19:38 -04:00
14 changed files with 260 additions and 42 deletions

View File

@@ -14,6 +14,7 @@ import org.springframework.ide.vscode.boot.java.completions.BootJavaCompletionEn
import org.springframework.ide.vscode.boot.java.completions.BootJavaReconcileEngine;
import org.springframework.ide.vscode.boot.java.hover.BootJavaHoverProvider;
import org.springframework.ide.vscode.boot.java.references.BootJavaReferencesHandler;
import org.springframework.ide.vscode.boot.java.symbols.BootJavaDocumentSymbolHandler;
import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
import org.springframework.ide.vscode.commons.gradle.GradleCore;
import org.springframework.ide.vscode.commons.gradle.GradleProjectFinderStrategy;
@@ -68,6 +69,7 @@ public class BootJavaLanguageServer extends SimpleLanguageServer {
ReferencesHandler referencesHandler = new BootJavaReferencesHandler(this, javaProjectFinder);
documents.onReferences(referencesHandler);
documents.onDocumentSymbol(new BootJavaDocumentSymbolHandler(this, javaProjectFinder));
}
public void setMaxCompletionsNumber(int number) {

View File

@@ -0,0 +1,184 @@
/*******************************************************************************
* Copyright (c) 2017 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.symbols;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
import org.eclipse.lsp4j.DocumentSymbolParams;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.SymbolKind;
import org.springframework.ide.vscode.commons.java.IClasspath;
import org.springframework.ide.vscode.commons.java.IJavaProject;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.DocumentSymbolHandler;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
import org.springframework.ide.vscode.commons.util.text.IDocument;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
/**
* @author Martin Lippert
*/
public class BootJavaDocumentSymbolHandler implements DocumentSymbolHandler {
private SimpleLanguageServer server;
private JavaProjectFinder projectFinder;
public BootJavaDocumentSymbolHandler(SimpleLanguageServer server, JavaProjectFinder projectFinder) {
this.server = server;
this.projectFinder = projectFinder;
}
@Override
public List<? extends SymbolInformation> handle(DocumentSymbolParams params) {
SimpleTextDocumentService documents = server.getTextDocumentService();
TextDocument doc = documents.get(params.getTextDocument().getUri()).copy();
if (doc != null) {
try {
return provideDocumentSymbols(doc);
} catch (Exception e) {
e.printStackTrace();
}
}
return SimpleTextDocumentService.NO_SYMBOLS;
}
private List<? extends SymbolInformation> provideDocumentSymbols(TextDocument document) throws Exception {
ASTParser parser = ASTParser.newParser(AST.JLS8);
Map<String, String> options = JavaCore.getOptions();
JavaCore.setComplianceOptions(JavaCore.VERSION_1_8, options);
parser.setCompilerOptions(options);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setStatementsRecovery(true);
parser.setBindingsRecovery(true);
parser.setResolveBindings(true);
String[] classpathEntries = getClasspathEntries(document);
String[] sourceEntries = new String[] {};
parser.setEnvironment(classpathEntries, sourceEntries, null, true);
String docURI = document.getUri();
String unitName = docURI.substring(docURI.lastIndexOf("/"));
parser.setUnitName(unitName);
parser.setSource(document.get(0, document.getLength()).toCharArray());
CompilationUnit cu = (CompilationUnit) parser.createAST(null);
if (cu != null) {
System.out.println("AST node found: " + cu.getClass().getName());
return provideDocumentSymbolsForAnnotations(cu, document);
}
return null;
}
private List<? extends SymbolInformation> provideDocumentSymbolsForAnnotations(ASTNode node, TextDocument doc) {
List<SymbolInformation> result = new ArrayList<>();
ASTVisitor visitor = new ASTVisitor() {
@Override
public boolean visit(AnnotationTypeDeclaration node) {
// TODO Auto-generated method stub
return super.visit(node);
}
@Override
public boolean visit(SingleMemberAnnotation node) {
ITypeBinding type = node.resolveTypeBinding();
if (type != null) {
String qualifiedName = type.getQualifiedName();
if (qualifiedName != null && qualifiedName.startsWith("org.springframework")) {
provideDocumentSymbolsForSpringAnnotations(node, type, doc, result);
}
}
return super.visit(node);
}
@Override
public boolean visit(AnnotationTypeMemberDeclaration node) {
// TODO Auto-generated method stub
return super.visit(node);
}
@Override
public boolean visit(MemberValuePair node) {
// TODO Auto-generated method stub
return super.visit(node);
}
@Override
public boolean visit(NormalAnnotation node) {
ITypeBinding type = node.resolveTypeBinding();
if (type != null) {
String qualifiedName = type.getQualifiedName();
if (qualifiedName != null && qualifiedName.startsWith("org.springframework")) {
provideDocumentSymbolsForSpringAnnotations(node, type, doc, result);
}
}
return super.visit(node);
}
@Override
public boolean visit(MarkerAnnotation node) {
ITypeBinding type = node.resolveTypeBinding();
if (type != null) {
String qualifiedName = type.getQualifiedName();
if (qualifiedName != null && qualifiedName.startsWith("org.springframework")) {
provideDocumentSymbolsForSpringAnnotations(node, type, doc, result);
}
}
return super.visit(node);
}
};
node.accept(visitor);
return result;
}
private void provideDocumentSymbolsForSpringAnnotations(Annotation node, ITypeBinding type,
TextDocument doc, List<SymbolInformation> resultAccumulator) {
try {
resultAccumulator.add(new SymbolInformation(node.toString(), SymbolKind.Interface, new Location(doc.getUri(),
doc.toRange(node.getStartPosition(), node.getLength()))));
}
catch (Exception e) {
e.printStackTrace();
}
}
private String[] getClasspathEntries(IDocument doc) throws Exception {
IJavaProject project = this.projectFinder.find(doc);
IClasspath classpath = project.getClasspath();
Stream<Path> classpathEntries = classpath.getClasspathEntries();
return classpathEntries
.filter(path -> path.toFile().exists())
.map(path -> path.toAbsolutePath().toString()).toArray(String[]::new);
}
}

View File

@@ -0,0 +1 @@
*Required*. Name of a stemcell used in the deployment.

View File

@@ -0,0 +1 @@
Full name of a matching stemcell. Either `name` or `os` keys can be specified.

View File

@@ -0,0 +1 @@
Operating system of a matching stemcell. Example: `ubuntu-trusty`. Either `name` or `os` keys can be specified.

View File

@@ -0,0 +1 @@
*Required*. The version of a matching stemcell. Version can be `latest`.

View File

@@ -213,6 +213,22 @@ public class BoshEditorTest {
);
}
@Test public void stemcellHovers() throws Exception {
Editor editor = harness.newEditor(
"stemcells:\n" +
"- alias: default\n" +
" os: ubuntu-trusty\n" +
" version: 3147\n" +
" name: bosh-aws-xen-hvm-ubuntu-trusty-go_agent"
);
editor.assertHoverContains("alias", "Name of a stemcell used in the deployment");
editor.assertHoverContains("os", "Operating system of a matching stemcell");
editor.assertHoverContains("version", "The version of a matching stemcell");
editor.assertHoverContains("name", "Full name of a matching stemcell. Either `name` or `os` keys can be specified.");
}
@Test public void releasesBlockCompletions() throws Exception {
Editor editor = harness.newEditor(
"releases:\n" +

View File

@@ -72,7 +72,6 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
if (id!=null) {
Consumer<CompletionItem> resolver = resolvers.get(id);
if (resolver!=null) {
Log.info("Resolving lazy completion item: "+unresolved.getLabel());
resolver.accept(unresolved);
unresolved.setData(null); //No longer needed after item is resolved.
} else {

View File

@@ -219,6 +219,7 @@ public class SimpleTextDocumentService implements TextDocumentService {
public final static CompletionList NO_COMPLETIONS = new CompletionList(false, Collections.emptyList());
public final static CompletableFuture<Hover> NO_HOVER = CompletableFuture.completedFuture(new Hover(ImmutableList.of(), null));
public final static CompletableFuture<List<? extends Location>> NO_REFERENCES = CompletableFuture.completedFuture(ImmutableList.of());
public final static List<? extends SymbolInformation> NO_SYMBOLS = ImmutableList.of();
@Override
public CompletableFuture<Either<List<CompletionItem>, CompletionList>> completion(TextDocumentPositionParams position) {
@@ -369,7 +370,11 @@ public class SimpleTextDocumentService implements TextDocumentService {
}
public synchronized TextDocument get(TextDocumentPositionParams params) {
TrackedDocument td = documents.get(params.getTextDocument().getUri());
return get(params.getTextDocument().getUri());
}
public synchronized TextDocument get(String uri) {
TrackedDocument td = documents.get(uri);
return td == null ? null : td.getDocument();
}

View File

@@ -3,14 +3,17 @@
"version": "0.1.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"name": "Launch Extension",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
"stopOnEntry": false,
"args": [
"--extensionDevelopmentPath=${workspaceRoot}"
],
"sourceMaps": true,
"outFiles": ["${workspaceRoot}/out/lib"],
"outFiles": [
"${workspaceRoot}/out/**/*.js"
],
"preLaunchTask": "npm"
},
{

View File

@@ -1,7 +1,7 @@
// 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
"out": false, // set this to true to hide the "out" folder with the compiled JS files
"node_modules": false,
"target": true
},

View File

@@ -22,7 +22,6 @@
"java", "spring-boot"
],
"activationEvents": [
"onLanguage:ini",
"onLanguage:java"
],
"main": "./out/lib/Main",

View File

@@ -1,20 +1,37 @@
# Concourse Pipeline and Task Editor for Visual Studio Code
# Bosh Deployment Manifest Editor for Visual Studio Code
This extension provides validation, content assist and documentation hovers
for editing [Concourse](https://concourse.ci/) Pipeline and Task configuration files.
for editing [Bosh](https://bosh.io/) Deployment Manifest files.
## Usage
The Concourse editor automatically activates when the name of the `.yml` file you are editing
### Activating the Editor
The Bosh editor automatically activates when the name of the `.yml` file you are editing
follows a certain pattern:
- `**/*pipeline*.yml` : activates support for editing pipelines
- `**/tasks/*.yml` : activates support for editing tasks.
- `**/*deployment*.yml` : activates support for bosh manifest file.
You can also define your own patterns and map them to the language-ids `concourse-pipeline-yaml`
or `concourse-task-yaml` by defining `files.associations` in workspace settings.
You can also define your own patterns and map them to the language-id `bosh-deployment-manifest`
by defining `files.associations` in workspace settings.
See [vscode documentation](https://code.visualstudio.com/Docs/languages/overview#_adding-a-file-extension-to-a-language) for details.
### Targetting a specific Director
Some Validation and Content Assist use information dymanically retrieved from an active Bosh director.
For these feature to work it is required that you
- have the bosh cli V2 installed (information is obtained by executing commands using the V2 cli)
- target a director by setting the `BOSH_ENVIROMENT` variable.
You can verify that you have set things up right by executing command:
```
bosh cloud-config --json
```
If setup correctly, it should return information about the cloud-config on your intended bosh director/environment.
## Functionality
### Validation
@@ -27,8 +44,7 @@ an error marker to see an explanation:
### Content assist
Having trouble remembering all the names of the attributes, and their spelling? Or can't remember
which resource properties to set in the `get` task params versus its `source` attributes? Or
don't remember what 'special' values are acceptable for a certain property? Content assist
the exact name/version of the stemcell you just uploaded to your bosh environment? Content assist
to the rescue:
![Content Assist Screenshot][ca1]
@@ -44,11 +60,11 @@ read its detailed documentation:
### Goto Symbol in File
Is your Pipeline yaml file getting larger and is it becoming harder to find a particular Job, Resource or
Resource Type declaration? The "Goto Symbol in File" command helps you quickly jump to a specific
Is your Deployment Manifest getting larger and is it becoming harder to find a particular Instance Group,
Release, or Stemcell definition? The "Goto Symbol in File" command helps you quickly jump to a specific
definition.
Type `CTRL-SHIFT-O` to popup a list of all symbols in your current Pipeline file. Start typing a name
Type `CTRL-SHIFT-O` to popup a list of all symbols in your current file. Start typing a name
(or portion thereof) to narrow down the list. Select a symbol to jump directly to its location in the
file.
@@ -56,36 +72,26 @@ file.
### Goto/Peek Definition
Use "Goto Defition" or "Peek Definition" to quickly go (or peek) from a a Job- or Resource name
Use "Goto Defition" or "Peek Definition" to quickly go (or peek) from a Release or Stemcell name
to its corresponding definition.
![Peek Definition Screenshot][peek]
## Limitations
### V2 versus V1 Schena
This Vscode Extension is still a work in progress. At the moment only a select few of the [built-in resource-types](https://concourse.ci/resource-types.html)
have been fully defined in the Editor's Schema.
The editor is intended primarily to support editing manifests in the [V2 schema](https://bosh.io/docs/manifest-v2.html).
When you use attributes from the V1 schema the editor will detect this however and switch to 'V1 tolerance' mode.
The resource-types that are already defined in the schema are:
- git
- docker-image
- s3
- pool
- semver
- time
For other resource-types content assist and checking is still very limited. We intend
to grow this list and provide a similar level of support for all of the built-in resource types in
the near future.
In this mode, V1 properties are accepted but marked with deprecation warnings and V2 properties are marked as (unknown property)
errors.
## Issues and Feature Requests
Please report bugs, issues and feature requests on the [Github STS4 issue tracker](https://github.com/spring-projects/sts4/issues).
[linting]: https://raw.githubusercontent.com/spring-projects/sts4/98148c08b608ff365fb87b2de955d6833f7ee082/vscode-extensions/vscode-concourse/readme-imgs/linting.png
[ca1]: https://raw.githubusercontent.com/spring-projects/sts4/98148c08b608ff365fb87b2de955d6833f7ee082/vscode-extensions/vscode-concourse/readme-imgs/content-assist-1.png
[ca2]: https://raw.githubusercontent.com/spring-projects/sts4/98148c08b608ff365fb87b2de955d6833f7ee082/vscode-extensions/vscode-concourse/readme-imgs/content-assist-2.png
[hovers]: https://raw.githubusercontent.com/spring-projects/sts4/98148c08b608ff365fb87b2de955d6833f7ee082/vscode-extensions/vscode-concourse/readme-imgs/hover.png
[peek]: https://raw.githubusercontent.com/spring-projects/sts4/98148c08b608ff365fb87b2de955d6833f7ee082/vscode-extensions/vscode-concourse/readme-imgs/peek.png
[goto_symbol]: https://raw.githubusercontent.com/spring-projects/sts4/d095208cfb34b0f129e6b66d41d099955a712f81/vscode-extensions/vscode-concourse/readme-imgs/goto-symbol.png
[linting]: https://raw.githubusercontent.com/spring-projects/sts4/master/vscode-extensions/vscode-bosh/readme-imgs/linting.png
[ca1]: https://raw.githubusercontent.com/spring-projects/sts4/master/vscode-extensions/vscode-bosh/readme-imgs/content-assist-1.png
[ca2]: https://raw.githubusercontent.com/spring-projects/sts4/master/vscode-extensions/vscode-bosh/readme-imgs/content-assist-2.png
[hovers]: https://raw.githubusercontent.com/spring-projects/sts4/master/vscode-extensions/vscode-bosh/readme-imgs/hover.png
[peek]: https://raw.githubusercontent.com/spring-projects/sts4/master/vscode-extensions/vscode-bosh/readme-imgs/peek.png
[goto_symbol]: https://raw.githubusercontent.com/spring-projects/sts4/master/vscode-extensions/vscode-bosh/readme-imgs/goto-symbol.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 73 KiB