Merge branch 'master' of github.com:spring-projects/sts4

This commit is contained in:
Kris De Volder
2016-12-07 09:59:39 -08:00
18 changed files with 257 additions and 166 deletions

View File

@@ -1,75 +1,70 @@
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>application-properties-metadata</artifactId>
<description>Builds metadata for boot application properties based on project's classpath contents</description>
<repositories>
<repository>
<id>project-repo</id>
<url>file://${project.basedir}/repo</url>
</repository>
</repositories>
<dependencies>
<!-- Local modified JSON lib packaged to support order in maps -->
<dependency>
<groupId>org.springframework.ide.eclipse</groupId>
<artifactId>org.json</artifactId>
<version>1.0</version>
</dependency>
<!-- Guava collections -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<!-- Javax Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Reactor -->
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>${reactor-version}</version>
</dependency>
<!-- Common Utilities -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-yaml</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-java</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-language-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>project-test-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>application-properties-metadata</artifactId>
<description>Builds metadata for boot application properties based on project's classpath contents</description>
<repositories>
<repository>
<id>project-repo</id>
<url>file://${project.basedir}/repo</url>
</repository>
</repositories>
<dependencies>
<!-- Local modified JSON lib packaged to support order in maps -->
<dependency>
<groupId>org.springframework.ide.eclipse</groupId>
<artifactId>org.json</artifactId>
<version>1.0</version>
</dependency>
<!-- Guava collections -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<!-- Javax Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Reactor -->
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>
<version>${reactor-version}</version>
</dependency>
<!-- Common Utilities -->
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-yaml</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>commons-java</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ide.vscode</groupId>
<artifactId>project-test-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,116 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015, 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.application.properties.metadata.completions;
import org.eclipse.lsp4j.CompletionItemKind;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
import org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.util.Renderable;
import org.springframework.ide.vscode.commons.yaml.hover.YPropertyHoverInfo;
import org.springframework.ide.vscode.commons.yaml.schema.YType;
import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil;
public abstract class AbstractPropertyProposal extends ScoreableProposal {
@Override
public String getDetail() {
return niceTypeName(getType());
}
protected final IDocument fDoc;
private final DocumentEdits proposalApplier;
private boolean isDeprecated = false;
public AbstractPropertyProposal(IDocument doc, DocumentEdits applier) {
this.proposalApplier = applier;
this.fDoc = doc;
}
@Override
public String getLabel() {
return getBaseDisplayString();
}
// public IRegion getSelection(IDocument document) {
// try {
// return proposalApplier.getSelection(document);
// } catch (Exception e) {
// Log.log(e);
// return null;
// }
// }
// public String getDisplayString() {
// StyledString styledText = getStyledDisplayString();
// return styledText.getString();
// }
// public Image getImage() {
// return null;
// }
// public IContextInformation getContextInformation() {
// return null;
// }
// @Override
// public StyledString getStyledDisplayString() {
// StyledString result = new StyledString();
// result = result.append(super.getStyledDisplayString());
// YType type = getType();
// if (type!=null) {
// String typeStr = niceTypeName(type);
// result.append(" : "+typeStr, StyledString.DECORATIONS_STYLER);
// }
// return result;
// }
protected boolean isDeprecated() {
return isDeprecated;
}
public void deprecate() {
if (!isDeprecated()) {
deemphasize();
deemphasize();
isDeprecated = true;
}
}
protected abstract YType getType();
protected abstract String getHighlightPattern();
protected abstract String getBaseDisplayString();
protected abstract String niceTypeName(YType type);
@Override
public CompletionItemKind getKind() {
return CompletionItemKind.Field;
}
@Override
public String toString() {
return getBaseDisplayString();
}
@Override
public final DocumentEdits getTextEdit() {
return this.proposalApplier;
}
// @Override
// public void apply(IDocument document) {
// try {
// proposalApplier.apply(document);
// } catch (Exception e) {
// EditorSupportActivator.log(e);
// }
// }
}

View File

@@ -1,185 +0,0 @@
/*******************************************************************************
* Copyright (c) 2014-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.application.properties.metadata.completions;
import org.eclipse.lsp4j.CompletionItemKind;
import org.springframework.ide.vscode.application.properties.metadata.PropertyInfo;
import org.springframework.ide.vscode.application.properties.metadata.hints.ValueHintHoverInfo;
import org.springframework.ide.vscode.application.properties.metadata.types.Type;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeParser;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil;
import org.springframework.ide.vscode.application.properties.metadata.types.TypedProperty;
import org.springframework.ide.vscode.application.properties.metadata.util.FuzzyMap.Match;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal;
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
import org.springframework.ide.vscode.commons.util.Renderable;
import org.springframework.ide.vscode.commons.yaml.hover.YPropertyHoverInfo;
import org.springframework.ide.vscode.commons.yaml.schema.YType;
public class PropertyCompletionFactory {
public ICompletionProposal valueProposal(String value, String query, String niceTypeName, double score, DocumentEdits edits, Renderable info) {
return new ScoreableProposal() {
@Override
public DocumentEdits getTextEdit() {
return edits;
}
@Override
public String getLabel() {
return value;
}
@Override
public CompletionItemKind getKind() {
return CompletionItemKind.Value;
}
@Override
public double getBaseScore() {
return score;
}
@Override
public String getDetail() {
return niceTypeName;
}
@Override
public Renderable getDocumentation() {
return info;
}
};
}
public ScoreableProposal property(IDocument doc, DocumentEdits applier, Match<PropertyInfo> prop, TypeUtil typeUtil) {
return new PropertyProposal(doc, applier, prop, typeUtil);
}
public ScoreableProposal beanProperty(IDocument doc, final String contextProperty, final Type contextType, final String pattern, final TypedProperty property, final double score, DocumentEdits applier, final TypeUtil typeUtil) {
AbstractPropertyProposal proposal = new AbstractPropertyProposal(doc, applier) {
@Override
public Renderable getDocumentation() {
return YPropertyHoverInfo.create(contextProperty, contextType, property);
}
@Override
protected String getBaseDisplayString() {
return property.getName();
}
@Override
protected String getHighlightPattern() {
return pattern;
}
@Override
protected Type getType() {
return property.getType();
}
@Override
public double getBaseScore() {
return score;
}
@Override
protected String niceTypeName(YType type) {
return typeUtil.niceTypeName((Type) type);
}
@Override
public String getLabel() {
return getBaseDisplayString() + " : " + typeUtil.niceTypeName(getType());
}
};
if (property.isDeprecated()) {
proposal.deprecate();
}
return proposal;
}
private JavaProjectFinder documentContextFinder;
public PropertyCompletionFactory(JavaProjectFinder documentContextFinder) {
this.documentContextFinder = documentContextFinder;
}
private class PropertyProposal extends AbstractPropertyProposal {
private Match<PropertyInfo> match;
private Type type;
private TypeUtil typeUtil;
public PropertyProposal(IDocument doc, DocumentEdits applier, Match<PropertyInfo> match,
TypeUtil typeUtil) {
super(doc, applier);
this.typeUtil = typeUtil;
this.match = match;
if (match.data.isDeprecated()) {
deprecate();
}
}
// @Override
// public HoverInfo getAdditionalProposalInfo(IProgressMonitor monitor) {
// return new SpringPropertyHoverInfo(documentContextFinder.getJavaProject(fDoc), match.data);
// }
@Override
protected String getBaseDisplayString() {
return match.data.getId();
}
@Override
public double getBaseScore() {
return match.score;
}
@Override
protected Type getType() {
if (type==null) {
type = TypeParser.parse(match.data.getType());
}
return type;
}
@Override
protected String getHighlightPattern() {
return match.getPattern();
}
@Override
protected String niceTypeName(YType type) {
return typeUtil.niceTypeName(((Type)type));
}
@Override
public String getLabel() {
return getBaseDisplayString();
}
@Override
public Renderable getDocumentation() {
//TODO: See org.springframework.ide.eclipse.boot.properties.editor.completions.SpringPropertyHoverInfo in old code on how
// this used to render docs.
return null;
}
}
}

View File

@@ -1,42 +0,0 @@
package org.springframework.ide.vscode.application.properties.metadata.completions;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil.BeanPropertyNameMode;
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil.EnumCaseMode;
/**
* Config object that determines some aspects of how the freedom of 'relaxed name binding'
* are taken into account when generating content-assist completions.
*
* @author Kris De Volder
*/
public class RelaxedNameConfig {
public static final RelaxedNameConfig ALIASSED = new RelaxedNameConfig(EnumCaseMode.ALIASED, BeanPropertyNameMode.ALIASED);
public static final RelaxedNameConfig COMPLETION_DEFAULTS = new RelaxedNameConfig(EnumCaseMode.LOWER_CASE, BeanPropertyNameMode.HYPHENATED);
private EnumCaseMode enumMode = EnumCaseMode.LOWER_CASE;
private BeanPropertyNameMode beanMode = BeanPropertyNameMode.HYPHENATED;
public RelaxedNameConfig(EnumCaseMode enumMode, BeanPropertyNameMode beanMode) {
this.enumMode = enumMode;
this.beanMode = beanMode;
}
public EnumCaseMode getEnumMode() {
return enumMode;
}
public void setEnumMode(EnumCaseMode preferredEnumCompletions) {
this.enumMode = preferredEnumCompletions;
}
public BeanPropertyNameMode getBeanMode() {
return beanMode;
}
public void setBeanMode(BeanPropertyNameMode preferredBeanCompletions) {
this.beanMode = preferredBeanCompletions;
}
@Override
public String toString() {
return "RelaxedNameConfig("+enumMode+", "+beanMode+")";
}
}

View File

@@ -3,7 +3,7 @@ package org.springframework.ide.vscode.languageserver.testharness;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.springframework.ide.vscode.languageserver.testharness.TestAsserts.*;
import static org.springframework.ide.vscode.languageserver.testharness.TestAsserts.assertContains;
import java.util.ArrayList;
import java.util.Collections;
@@ -24,10 +24,8 @@ import org.eclipse.lsp4j.PublishDiagnosticsParams;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
import org.junit.Assert;
import org.springframework.ide.vscode.commons.util.Log;
import com.google.common.base.Strings;
import com.google.gson.internal.Streams;
public class Editor {
@@ -206,7 +204,6 @@ public class Editor {
: "";
}
@SuppressWarnings("unchecked")
private List<Diagnostic> reconcile() {
// We assume the language server works synchronously for now and it does an immediate reconcile
// when the document changes. In the future this is probably not going to be the case though and then this
@@ -351,7 +348,9 @@ public class Editor {
if (expectDetail!=null) {
assertEquals(expectDetail, it.getDetail());
}
assertContains(expectDocSnippet, it.getDocumentation());
if (expectDocSnippet!=null) {
assertContains(expectDocSnippet, it.getDocumentation());
}
}
protected CompletionItem assertCompletionWithLabel(String expectLabel) throws Exception {

View File

@@ -1,5 +1,6 @@
package org.springframework.ide.vscode.properties.editor.test.harness;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
@@ -102,23 +103,20 @@ public abstract class AbstractPropsEditorTest {
harness.assertCompletionDisplayString(editorContents, expected);
}
private void notImplemented() {
throw new UnsupportedOperationException("Not yet implemented");
}
/**
* Checks that completions contains a completion with a given display string and that that completion
* has a info hover that contains a given snippet of text.
* <p>
* Deprecated: use assertCompletionDetails instead and also check add an expected 'detail' text of
* completion item.
*/
@Deprecated
public void assertCompletionWithInfoHover(String editorText, String expectLabel, String expectInfoSnippet) throws Exception {
Editor editor = newEditor(editorText);
editor.assertCompletionDetails(expectLabel, null, expectInfoSnippet);
}
/**
* Checks that completions contains a completion with a given display string, detail and documentation text
*/
public void assertCompletionDetails(String editorText, String expectLabel, String expectDetail, String expectDocumenation) throws Exception {
Editor editor = newEditor(editorText);
editor.assertCompletionDetails(expectLabel, expectDetail, expectDocumenation);
}
public boolean isEmptyMetadata() {
return md.isEmpty();
}
@@ -174,6 +172,25 @@ public abstract class AbstractPropsEditorTest {
}
assertElements(actualLabels, completionsLabels);
}
public void assertCompletionsDisplayStringAndDetail(String editorText, String[]...expectCompletions) throws Exception {
String[] completionsLabels = new String[expectCompletions.length];
String[] completionDetails = new String[expectCompletions.length];
for (int i = 0; i < expectCompletions.length; i++) {
completionsLabels[i] = expectCompletions[i][0];
completionDetails[i] = expectCompletions[i][1];
}
Editor editor = newEditor(editorText);
List<CompletionItem> completions = editor.getCompletions();
String[] actualLabels = new String[completions.size()];
String[] actualDetails = new String[completions.size()];
for (int i = 0; i < completions.size(); i++) {
actualLabels[i] = completions.get(i).getLabel();
actualDetails[i] = completions.get(i).getDetail();
}
assertElements(actualLabels, completionsLabels);
assertArrayEquals(actualDetails, completionDetails);
}
public SpringPropertyIndexProvider getIndexProvider() {
return md.getIndexProvider();