Quickfix for health-check-type: none
This commit is contained in:
@@ -32,15 +32,15 @@ import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
|
||||
/**
|
||||
* This class is a placeholder where we will attempt to copy and port
|
||||
* as many tests a possible from
|
||||
* as many tests a possible from
|
||||
* org.springframework.ide.eclipse.boot.properties.editor.test.YamlEditorTests
|
||||
*
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@Test public void linterRunsOnDocumentOpenAndChange() throws Exception {
|
||||
Editor editor = newEditor(
|
||||
"somemap: val\n"+
|
||||
@@ -50,7 +50,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
editor.assertProblems(
|
||||
"-|expected <block end>"
|
||||
);
|
||||
|
||||
|
||||
editor.setText(
|
||||
"- sequence\n" +
|
||||
"zomemap: val"
|
||||
@@ -60,9 +60,9 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
"z|expected <block end>"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
///////////////////// ported tests from old STS code base ////////////////////////////////////////////////
|
||||
|
||||
|
||||
@Test public void testHovers() throws Exception {
|
||||
defaultTestData();
|
||||
Editor editor = newEditor(
|
||||
@@ -212,7 +212,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
editor.assertHoverContains("data", "Pojo"); // description from json metadata
|
||||
|
||||
|
||||
// NOTE: This may be failing because javadoc may not be obtained from a private member
|
||||
editor.assertHoverContains("wavelen", "JavaDoc from field"); // javadoc from field
|
||||
editor.assertHoverContains("name", "Set the name"); // javadoc from setter
|
||||
@@ -224,7 +224,6 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
}
|
||||
|
||||
@Ignore @Test public void testHyperlinkTargets() throws Exception {
|
||||
System.out.println(">>> testHyperlinkTargets");
|
||||
IJavaProject p = createPredefinedMavenProject("tricky-getters-boot-1.3.1-app");
|
||||
useProject(p);
|
||||
|
||||
@@ -248,7 +247,6 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
editor.assertLinkTargets("init-sql",
|
||||
"org.springframework.boot.autoconfigure.flyway.FlywayProperties.setInitSqls(List<String>)");
|
||||
System.out.println("<<< testHyperlinkTargets");
|
||||
}
|
||||
|
||||
@Test public void testReconcile() throws Exception {
|
||||
@@ -679,7 +677,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
"bad: BLUE|Expecting a 'demo.Color",
|
||||
"Bogus|Expecting a 'demo.Color"
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* TODO: if enums are not sorted by the 3rd party java indexing lib then
|
||||
* perform the commented out test rather than the above
|
||||
@@ -2360,11 +2358,11 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
*/
|
||||
@Test public void testDeprecatedReconcileProperty() throws Exception {
|
||||
data("error.path", "java.lang.String", null, "Path of the error controller.");
|
||||
|
||||
|
||||
String contents = "# a comment\n"+
|
||||
"error:\n"+
|
||||
" path: foo\n";
|
||||
|
||||
|
||||
Editor editor = newEditor(
|
||||
contents
|
||||
);
|
||||
@@ -3156,7 +3154,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Delete this tempotary test.
|
||||
* TODO: Delete this tempotary test.
|
||||
* This test is just one piece copied from another test to do more focussed debugging. If you find this test
|
||||
* in the git repo, then it was committed by accident. So feel free to delete it.
|
||||
*/
|
||||
@@ -3167,7 +3165,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
|
||||
data("my.nice.resource", "org.springframework.core.io.Resource", null, "A very nice resource.");
|
||||
data("my.nice.list", "java.util.List<org.springframework.core.io.Resource>", null, "A nice list of resources.");
|
||||
|
||||
|
||||
assertCompletionWithLabel(
|
||||
"my:\n" +
|
||||
" nice:\n" +
|
||||
@@ -3298,24 +3296,24 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
" classpath:stuff/wordlist.txt<*>\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Test public void testCompletionsInContextWithDuplicateKey() throws Exception {
|
||||
//See: https://www.pivotaltracker.com/story/show/135708013
|
||||
defaultTestData();
|
||||
|
||||
|
||||
assertCompletions(
|
||||
"spring:\n" +
|
||||
" application:\n" +
|
||||
" name: my-app\n" +
|
||||
"spring:\n" +
|
||||
" activemq:\n" +
|
||||
"spring:\n" +
|
||||
" application:\n" +
|
||||
" name: my-app\n" +
|
||||
"spring:\n" +
|
||||
" activemq:\n" +
|
||||
" broker-u<*>"
|
||||
, // ==>
|
||||
"spring:\n" +
|
||||
" application:\n" +
|
||||
" name: my-app\n" +
|
||||
"spring:\n" +
|
||||
" activemq:\n" +
|
||||
"spring:\n" +
|
||||
" application:\n" +
|
||||
" name: my-app\n" +
|
||||
"spring:\n" +
|
||||
" activemq:\n" +
|
||||
" broker-url: <*>"
|
||||
);
|
||||
}
|
||||
@@ -3596,7 +3594,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
@Test public void PT_137299017_extra_space_wth_bean_property_value_completion() throws Exception {
|
||||
useProject(createPredefinedMavenProject("enums-boot-1.3.2-app"));
|
||||
data("color", "demo.ColorData", null, "colorful stuff");
|
||||
|
||||
|
||||
assertCompletions(
|
||||
"color:\n" +
|
||||
" next:<*>"
|
||||
@@ -3615,17 +3613,17 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
@Test public void PT_137299017_extra_space_wth_index_property_value_completion() throws Exception {
|
||||
defaultTestData();
|
||||
assertCompletions(
|
||||
"flyway:\n"+
|
||||
"flyway:\n"+
|
||||
" enabled:<*>"
|
||||
, // ==>
|
||||
"flyway:\n"+
|
||||
"flyway:\n"+
|
||||
" enabled: false<*>"
|
||||
, // ==
|
||||
"flyway:\n"+
|
||||
"flyway:\n"+
|
||||
" enabled: true<*>"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
///////////////// cruft ////////////////////////////////////////////////////////
|
||||
|
||||
private void generateNestedProperties(int levels, String[] names, String prefix) {
|
||||
@@ -3656,5 +3654,5 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
protected String getFileExtension() {
|
||||
return ".yml";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.languageserver.reconcile;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParseException;
|
||||
|
||||
/**
|
||||
@@ -23,6 +25,8 @@ public class ReconcileException extends ValueParseException implements ProblemTy
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final ProblemType problemType;
|
||||
|
||||
private ReplacementQuickfix replacement = null; //Optional info to create a 'replacement quickfix' for the value
|
||||
|
||||
public ReconcileException(String message, ProblemType problemType) {
|
||||
super(message);
|
||||
this.problemType = problemType;
|
||||
@@ -37,4 +41,17 @@ public class ReconcileException extends ValueParseException implements ProblemTy
|
||||
public ProblemType getProblemType() {
|
||||
return problemType;
|
||||
}
|
||||
|
||||
public ReconcileException fixWith(ReplacementQuickfix replacement) {
|
||||
//Silently ignore if the fix is either null or doesn't provide a proper replacement text.
|
||||
if (replacement!=null && StringUtil.hasText(replacement.replacement)) {
|
||||
Assert.isLegal(this.replacement==null, "Multiple fixes not yet supported");
|
||||
this.replacement = replacement;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReplacementQuickfix getReplacement() {
|
||||
return replacement;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*******************************************************************************
|
||||
* 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.commons.languageserver.reconcile;
|
||||
|
||||
/**
|
||||
* An info object that can be attached to a {@link ReconcileException} to indicate that
|
||||
* the problem can be fixed by a simple value substitution at the exact location of
|
||||
* the problem marker.
|
||||
*
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class ReplacementQuickfix {
|
||||
public final String msg;
|
||||
public final String replacement;
|
||||
public ReplacementQuickfix(String msg, String replacement) {
|
||||
super();
|
||||
this.msg = msg;
|
||||
this.replacement = replacement;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ReplacementQuickfix [msg=" + msg + ", replacement=" + replacement + "]";
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
@@ -290,4 +291,8 @@ public class DocumentRegion implements CharSequence {
|
||||
numChars = Math.min(getLength(), numChars);
|
||||
return new DocumentRegion(doc, end-numChars, end);
|
||||
}
|
||||
|
||||
public Range asRange() throws BadLocationException {
|
||||
return doc.toRange(asRegion());
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
package org.springframework.ide.vscode.commons.util.text;
|
||||
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
|
||||
public interface IDocument {
|
||||
@@ -30,5 +31,6 @@ public interface IDocument {
|
||||
String textBetween(int start, int end) throws BadLocationException;
|
||||
LanguageId getLanguageId();
|
||||
int getVersion();
|
||||
Range toRange(IRegion asRegion) throws BadLocationException;
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
package org.springframework.ide.vscode.commons.util.text;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -278,6 +277,7 @@ public class TextDocument implements IDocument {
|
||||
return languageId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Range toRange(IRegion region) throws BadLocationException {
|
||||
return toRange(region.getOffset(), region.getLength());
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.reconcile;
|
||||
package org.springframework.ide.vscode.commons.yaml.quickfix;
|
||||
|
||||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
@@ -21,6 +21,8 @@ import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.YamlPathEdits;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.MissingPropertiesData;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.ReplaceStringData;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SChildBearingNode;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode;
|
||||
@@ -33,6 +35,7 @@ import com.google.common.collect.ImmutableMap;
|
||||
public class YamlQuickfixes {
|
||||
|
||||
public final QuickfixType MISSING_PROP_FIX;
|
||||
public final QuickfixType SIMPLE_TEXT_EDIT;
|
||||
|
||||
public YamlQuickfixes(QuickfixRegistry r, SimpleTextDocumentService textDocumentService, YamlStructureProvider structureProvider) {
|
||||
MISSING_PROP_FIX = r.register("MISSING_PROP_FIX", (Object _params) -> {
|
||||
@@ -69,6 +72,24 @@ public class YamlQuickfixes {
|
||||
//Something went wrong. Return empty edit object.
|
||||
return new WorkspaceEdit(ImmutableMap.of(), null);
|
||||
});
|
||||
|
||||
SIMPLE_TEXT_EDIT = r.register("SIMPLE_TEXT_EDIT", (_params) -> {
|
||||
try {
|
||||
ReplaceStringData params = new ObjectMapper().convertValue(_params, ReplaceStringData.class);
|
||||
TextDocument _doc = textDocumentService.getDocument(params.getUri());
|
||||
if (_doc!=null) {
|
||||
return new WorkspaceEdit(
|
||||
ImmutableMap.of(params.getUri(), ImmutableList.of(params.getEdit())),
|
||||
null
|
||||
);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
//Something went wrong. Return empty edit object.
|
||||
//Something went wrong. Return empty edit object.
|
||||
return new WorkspaceEdit(ImmutableMap.of(), null);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*******************************************************************************
|
||||
* 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.commons.yaml.reconcile;
|
||||
|
||||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
|
||||
public class ReplaceStringData {
|
||||
|
||||
private String uri;
|
||||
private TextEdit edit;
|
||||
|
||||
public ReplaceStringData() {}
|
||||
|
||||
public ReplaceStringData(DocumentRegion target, String newText) throws BadLocationException {
|
||||
this.uri = target.getDocument().getUri();
|
||||
this.edit = new TextEdit(target.asRange(), newText);
|
||||
}
|
||||
|
||||
public TextEdit getEdit() {
|
||||
return edit;
|
||||
}
|
||||
public void setEdit(TextEdit edit) {
|
||||
this.edit = edit;
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ReplaceStringData [uri=" + uri + ", edit=" + edit + "]";
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,13 @@ import java.util.TreeSet;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix.QuickfixData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemTypeProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileException;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReplacementQuickfix;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
import org.springframework.ide.vscode.commons.util.IntegerRange;
|
||||
@@ -38,9 +42,9 @@ import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
|
||||
import org.springframework.ide.vscode.commons.yaml.quickfix.YamlQuickfixes;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.ASTDynamicSchemaContext;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.SchemaContextAware;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty;
|
||||
@@ -181,21 +185,9 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ProblemType problemType = getProblemType(e);
|
||||
DocumentRegion region = new DocumentRegion(doc, node.getStartMark().getIndex(), node.getEndMark().getIndex());
|
||||
if (e instanceof ValueParseException) {
|
||||
ValueParseException parseException = (ValueParseException) e;
|
||||
int start = parseException.getStartIndex() >= 0
|
||||
? Math.min(node.getStartMark().getIndex() + parseException.getStartIndex(),
|
||||
node.getEndMark().getIndex())
|
||||
: node.getStartMark().getIndex();
|
||||
int end = parseException.getEndIndex() >= 0
|
||||
? Math.min(node.getStartMark().getIndex() + parseException.getEndIndex(),
|
||||
node.getEndMark().getIndex())
|
||||
: node.getEndMark().getIndex();
|
||||
region = new DocumentRegion(doc, start, end);
|
||||
}
|
||||
DocumentRegion region = getRegion(e, doc, node);
|
||||
String msg = getMessage(e);
|
||||
valueParseError(type, region, msg, problemType);
|
||||
valueParseError(type, region, msg, problemType, getValueReplacement(e));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -208,6 +200,31 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
|
||||
}
|
||||
}
|
||||
|
||||
protected ReplacementQuickfix getValueReplacement(Exception _e) {
|
||||
if (_e instanceof ReconcileException) {
|
||||
ReconcileException e = (ReconcileException) _e;
|
||||
return e.getReplacement();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected DocumentRegion getRegion(Exception e, IDocument doc, Node node) {
|
||||
DocumentRegion region = new DocumentRegion(doc, node.getStartMark().getIndex(), node.getEndMark().getIndex());
|
||||
if (e instanceof ValueParseException) {
|
||||
ValueParseException parseException = (ValueParseException) e;
|
||||
int start = parseException.getStartIndex() >= 0
|
||||
? Math.min(node.getStartMark().getIndex() + parseException.getStartIndex(),
|
||||
node.getEndMark().getIndex())
|
||||
: node.getStartMark().getIndex();
|
||||
int end = parseException.getEndIndex() >= 0
|
||||
? Math.min(node.getStartMark().getIndex() + parseException.getEndIndex(),
|
||||
node.getEndMark().getIndex())
|
||||
: node.getEndMark().getIndex();
|
||||
region = new DocumentRegion(doc, start, end);
|
||||
}
|
||||
return region;
|
||||
}
|
||||
|
||||
private String getMessage(Exception _e) {
|
||||
Throwable e = ExceptionUtil.getDeepestCause(_e);
|
||||
|
||||
@@ -337,18 +354,24 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
|
||||
}
|
||||
}
|
||||
|
||||
private void valueParseError(YType type, Node node, String parseErrorMsg, ProblemType problemType) {
|
||||
private void valueParseError(YType type, DocumentRegion region, String parseErrorMsg, ProblemType problemType, ReplacementQuickfix fix) {
|
||||
if (!StringUtil.hasText(parseErrorMsg)) {
|
||||
parseErrorMsg= "Couldn't parse as '"+describe(type)+"'";
|
||||
}
|
||||
problem(node, parseErrorMsg, problemType);
|
||||
}
|
||||
|
||||
private void valueParseError(YType type, DocumentRegion region, String parseErrorMsg, ProblemType problemType) {
|
||||
if (!StringUtil.hasText(parseErrorMsg)) {
|
||||
parseErrorMsg= "Couldn't parse as '"+describe(type)+"'";
|
||||
ReconcileProblemImpl problem = YamlSchemaProblems.problem(problemType, parseErrorMsg, region);
|
||||
if (fix!=null && StringUtil.hasText(fix.replacement)) {
|
||||
try {
|
||||
problem.addQuickfix(
|
||||
new QuickfixData<>(quickfixes.SIMPLE_TEXT_EDIT,
|
||||
new ReplaceStringData(region, fix.replacement),
|
||||
fix.msg
|
||||
)
|
||||
);
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
}
|
||||
problem(region, parseErrorMsg, problemType);
|
||||
problems.accept(problem);
|
||||
}
|
||||
|
||||
private void unknownBeanProperty(Node keyNode, YType type, String name) {
|
||||
@@ -404,14 +427,6 @@ public class SchemaBasedYamlASTReconciler implements YamlASTReconciler {
|
||||
problems.accept(YamlSchemaProblems.schemaProblem(msg, node));
|
||||
}
|
||||
|
||||
private void problem(Node node, String msg, ProblemType problemType) {
|
||||
problems.accept(YamlSchemaProblems.problem(problemType, msg, node));
|
||||
}
|
||||
|
||||
private void problem(DocumentRegion region, String msg, ProblemType problemType) {
|
||||
problems.accept(YamlSchemaProblems.problem(problemType, msg, region));
|
||||
}
|
||||
|
||||
private void problem(DocumentRegion region, String msg) {
|
||||
problems.accept(YamlSchemaProblems.schemaProblem(msg, region));
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemC
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlASTProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.quickfix.YamlQuickfixes;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YamlSchema;
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,6 +49,7 @@ public class YamlSchemaProblems {
|
||||
public static final ProblemType SYNTAX_PROBLEM = problemType("YamlSyntaxProblem");
|
||||
public static final ProblemType SCHEMA_PROBLEM = problemType("YamlSchemaProblem");
|
||||
public static final ProblemType DEPRECATED_PROPERTY = problemType("DeprecatedProperty", ProblemSeverity.WARNING);
|
||||
public static final ProblemType DEPRECATED_VALUE = problemType("DeprecatedValue", ProblemSeverity.WARNING);
|
||||
public static final ProblemType MISSING_PROPERTY = problemType("MissingProperty", ProblemSeverity.ERROR);
|
||||
public static final ProblemType EXTRA_PROPERTY = problemType("ExtraProperty", ProblemSeverity.ERROR);
|
||||
|
||||
|
||||
@@ -26,14 +26,13 @@ import java.util.function.BiFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileException;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReplacementQuickfix;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.EnumValueParser;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.AbstractType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraint;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraints;
|
||||
|
||||
@@ -53,12 +52,25 @@ import reactor.core.publisher.Flux;
|
||||
*/
|
||||
public class YTypeFactory {
|
||||
|
||||
private static class Deprecation {
|
||||
final String errorMsg;
|
||||
final String replacement;
|
||||
final String quickfixMsg;
|
||||
public Deprecation(String errorMsg, String replacement, String quickfixMsg) {
|
||||
super();
|
||||
this.errorMsg = errorMsg;
|
||||
this.replacement = replacement;
|
||||
this.quickfixMsg = quickfixMsg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class EnumTypeBuilder {
|
||||
|
||||
private String name;
|
||||
private String[] values;
|
||||
|
||||
private Map<String, String> deprecationMsgs = new HashMap<>();
|
||||
private Map<String, Deprecation> deprecations = new HashMap<>();
|
||||
|
||||
public EnumTypeBuilder(String name, String[] values) {
|
||||
this.name = name;
|
||||
@@ -69,17 +81,15 @@ public class YTypeFactory {
|
||||
EnumValueParser basicParser = new EnumValueParser(name, values);
|
||||
YAtomicType t = yatomic(name);
|
||||
t.addHints(getNonDeprecatedValues());
|
||||
if (deprecationMsgs.isEmpty()) {
|
||||
if (deprecations.isEmpty()) {
|
||||
t.parseWith(basicParser);
|
||||
} else {
|
||||
t.parseWith(ValueParser.of((String value) -> {
|
||||
basicParser.parse(value);
|
||||
if (deprecationMsgs.containsKey(value)) {
|
||||
String msg = deprecationMsgs.get(value);
|
||||
if (!StringUtil.hasText(msg)) {
|
||||
msg = "'"+value+"' is deprecated";
|
||||
}
|
||||
throw new ReconcileException(msg, YamlSchemaProblems.DEPRECATED_PROPERTY);
|
||||
Deprecation d = deprecations.get(value);
|
||||
if (d!=null) {
|
||||
throw new ReconcileException(d.errorMsg, YamlSchemaProblems.DEPRECATED_VALUE)
|
||||
.fixWith(new ReplacementQuickfix(d.quickfixMsg, d.replacement));
|
||||
}
|
||||
return value;
|
||||
}));
|
||||
@@ -89,13 +99,23 @@ public class YTypeFactory {
|
||||
|
||||
public EnumTypeBuilder deprecate(String value, String msg) {
|
||||
Assert.isLegal(ImmutableSet.copyOf(values).contains(value));
|
||||
deprecationMsgs.put(value, msg);
|
||||
deprecations.put(value, new Deprecation(msg, null, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
public EnumTypeBuilder deprecateWithReplacement(String value, String replacement) {
|
||||
Assert.isLegal(ImmutableSet.copyOf(values).contains(value));
|
||||
deprecations.put(value, new Deprecation(
|
||||
"The value '"+value+"' is deprecated in favor of '"+replacement+"'",
|
||||
replacement,
|
||||
"Replace deprecated value '"+value+"' by '"+replacement+"'"
|
||||
));
|
||||
return this;
|
||||
}
|
||||
|
||||
private String[] getNonDeprecatedValues() {
|
||||
return Flux.fromArray(values)
|
||||
.filter((value) -> !deprecationMsgs.containsKey(value))
|
||||
.filter((value) -> !deprecations.containsKey(value))
|
||||
.collectList()
|
||||
.map(l -> l.toArray(new String[l.size()]))
|
||||
.block();
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.springframework.ide.vscode.commons.yaml.ast.YamlASTProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.SchemaBasedYamlAssistContextProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.YamlCompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.yaml.hover.YamlHoverInfoProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlQuickfixes;
|
||||
import org.springframework.ide.vscode.commons.yaml.quickfix.YamlQuickfixes;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaBasedReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.springframework.ide.vscode.commons.yaml.completion.SchemaBasedYamlAss
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.YamlAssistContextProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.YamlCompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.yaml.hover.YamlHoverInfoProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlQuickfixes;
|
||||
import org.springframework.ide.vscode.commons.yaml.quickfix.YamlQuickfixes;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaBasedReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YamlSchema;
|
||||
|
||||
@@ -108,7 +108,7 @@ public class ManifestYmlSchema implements YamlSchema {
|
||||
t_memory.parseWith(ManifestYmlValueParsers.MEMORY);
|
||||
|
||||
YAtomicType t_health_check_type = f.yenumBuilder("Health Check Type", "none", "process", "port", "http")
|
||||
.deprecate("none", "The value 'none' is deprecated in favor of 'process'")
|
||||
.deprecateWithReplacement("none", "process")
|
||||
.build();
|
||||
|
||||
YAtomicType t_strictly_pos_integer = f.yatomic("Strictly Positive Integer");
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.springframework.ide.vscode.commons.cloudfoundry.client.CFDomain;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.CFServiceInstance;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.ClientRequests;
|
||||
import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.NoTargetsException;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.CodeAction;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
|
||||
@@ -440,12 +441,6 @@ public class ManifestYamlEditorTest {
|
||||
problem = editor.assertProblems("none|'none' is deprecated in favor of 'process'").get(0);
|
||||
assertEquals(DiagnosticSeverity.Warning, problem.getSeverity());
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: foo\n" +
|
||||
" health-check-type: none"
|
||||
);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: foo\n" +
|
||||
@@ -461,6 +456,25 @@ public class ManifestYamlEditorTest {
|
||||
editor.assertProblems(/*NONE*/);
|
||||
}
|
||||
|
||||
@Test public void deprecatedHealthCheckTypeQuickfix() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"applications:\n" +
|
||||
"- name: foo\n" +
|
||||
" health-check-type: none"
|
||||
);
|
||||
Diagnostic problem = editor.assertProblems("none|'none' is deprecated in favor of 'process'").get(0);
|
||||
assertEquals(DiagnosticSeverity.Warning, problem.getSeverity());
|
||||
CodeAction quickfix = editor.assertCodeAction(problem);
|
||||
assertEquals("Replace deprecated value 'none' by 'process'", quickfix.getLabel());
|
||||
quickfix.perform();
|
||||
|
||||
editor.assertRawText(
|
||||
"applications:\n" +
|
||||
"- name: foo\n" +
|
||||
" health-check-type: process"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hoverInfos() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
@@ -1147,6 +1161,7 @@ public class ManifestYamlEditorTest {
|
||||
editor.assertProblems();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void assertCompletions(String textBefore, String... textAfter) throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user