PT #135782951: (Part 2) Deprecated property quick fix
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* Copyright (c) 2017, 2019 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
|
||||
@@ -21,6 +21,7 @@ import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEd
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.text.IRegion;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.YamlPathEdits;
|
||||
@@ -80,16 +81,7 @@ public class YamlQuickfixes {
|
||||
}
|
||||
edits.insert(insertAt, indenter.applyIndentation(propSnippet.substring(cursorOffset), indentBy));
|
||||
}
|
||||
TextReplace replaceEdit = edits.asReplacement(_doc);
|
||||
if (replaceEdit!=null) {
|
||||
WorkspaceEdit wsEdits = new WorkspaceEdit();
|
||||
wsEdits.setChanges(ImmutableMap.of(
|
||||
params.getUri(),
|
||||
ImmutableList.of(new TextEdit(_doc.toRange(replaceEdit.getRegion()), replaceEdit.newText))
|
||||
));
|
||||
Position newCursor = getCursorPostionAfter(_doc, edits);
|
||||
return new QuickfixEdit(wsEdits, newCursor==null ? null : new CursorMovement(params.getUri(), newCursor));
|
||||
}
|
||||
return createReplacementQuickfic(_doc, edits);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,7 +112,21 @@ public class YamlQuickfixes {
|
||||
});
|
||||
}
|
||||
|
||||
private Position getCursorPostionAfter(TextDocument _doc, YamlPathEdits edits) {
|
||||
public static QuickfixEdit createReplacementQuickfic(TextDocument doc, YamlPathEdits edits) throws BadLocationException {
|
||||
TextReplace replaceEdit = edits.asReplacement(doc);
|
||||
if (replaceEdit!=null) {
|
||||
WorkspaceEdit wsEdits = new WorkspaceEdit();
|
||||
wsEdits.setChanges(ImmutableMap.of(
|
||||
doc.getUri(),
|
||||
ImmutableList.of(new TextEdit(doc.toRange(replaceEdit.getRegion()), replaceEdit.newText))
|
||||
));
|
||||
Position newCursor = getCursorPostionAfter(doc, edits);
|
||||
return new QuickfixEdit(wsEdits, newCursor==null ? null : new CursorMovement(doc.getUri(), newCursor));
|
||||
}
|
||||
return NULL_FIX;
|
||||
}
|
||||
|
||||
private static Position getCursorPostionAfter(TextDocument _doc, YamlPathEdits edits) {
|
||||
try {
|
||||
IRegion newSelection = edits.getSelection();
|
||||
if (newSelection!=null) {
|
||||
|
||||
@@ -783,8 +783,10 @@ public class Editor {
|
||||
return null; //unreachable but compiler doesn't know
|
||||
}
|
||||
|
||||
public CompletionItem assertFirstQuickfix(Diagnostic problem, String expectLabel) {
|
||||
throw new UnsupportedOperationException("Not implemented yet!");
|
||||
public CodeAction assertFirstQuickfix(Diagnostic problem, String expectLabel) throws Exception {
|
||||
CodeAction ca = assertCodeAction(problem);
|
||||
assertEquals(expectLabel, ca.getLabel());
|
||||
return ca;
|
||||
}
|
||||
|
||||
public void assertText(String expected) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2018 Pivotal, Inc.
|
||||
* Copyright (c) 2016, 2019 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
|
||||
@@ -19,7 +19,9 @@ import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider;
|
||||
import org.springframework.ide.vscode.boot.properties.completions.SpringPropertiesCompletionEngine;
|
||||
import org.springframework.ide.vscode.boot.properties.hover.PropertiesHoverInfoProvider;
|
||||
import org.springframework.ide.vscode.boot.properties.quickfix.AppPropertiesQuickFixes;
|
||||
import org.springframework.ide.vscode.boot.properties.reconcile.SpringPropertiesReconcileEngine;
|
||||
import org.springframework.ide.vscode.boot.yaml.quickfix.AppYamlQuickfixes;
|
||||
import org.springframework.ide.vscode.boot.yaml.reconcile.ApplicationYamlReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.composable.LanguageServerComponents;
|
||||
@@ -75,6 +77,9 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom
|
||||
private final SimpleLanguageServer server;
|
||||
private YamlASTProvider parser;
|
||||
|
||||
private SpringPropertiesReconcileEngine propertiesReconciler;
|
||||
private ApplicationYamlReconcileEngine ymlReconciler;
|
||||
|
||||
|
||||
public BootPropertiesLanguageServerComponents(
|
||||
SimpleLanguageServer server,
|
||||
@@ -91,7 +96,11 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom
|
||||
this.projectObserver = serverParams.projectObserver;
|
||||
this.yamlStructureProvider = yamlStructureProvider;
|
||||
this.yamlAssistContextProvider = yamlAssistContextProvider;
|
||||
|
||||
this.propertiesReconciler = new SpringPropertiesReconcileEngine(indexProvider,
|
||||
typeUtilProvider, new AppPropertiesQuickFixes(server.getQuickfixRegistry()));
|
||||
this.ymlReconciler = new ApplicationYamlReconcileEngine(parser, indexProvider, typeUtilProvider,
|
||||
new AppYamlQuickfixes(server.getQuickfixRegistry(), server.getTextDocumentService(),
|
||||
yamlStructureProvider));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,9 +146,6 @@ public class BootPropertiesLanguageServerComponents implements LanguageServerCom
|
||||
|
||||
@Override
|
||||
public Optional<IReconcileEngine> getReconcileEngine() {
|
||||
IReconcileEngine propertiesReconciler = new SpringPropertiesReconcileEngine(indexProvider, typeUtilProvider);
|
||||
IReconcileEngine ymlReconciler = new ApplicationYamlReconcileEngine(parser, indexProvider, typeUtilProvider);
|
||||
|
||||
return Optional.of((doc, problemCollector) -> {
|
||||
String uri = doc.getUri();
|
||||
if (uri!=null) {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019 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.properties.quickfix;
|
||||
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit.CursorMovement;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixType;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
/**
|
||||
* Boot app Properties file quick fix handlers
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class AppPropertiesQuickFixes {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AppPropertiesQuickFixes.class);
|
||||
|
||||
private static final QuickfixEdit NULL_FIX = new QuickfixEdit(
|
||||
new WorkspaceEdit(ImmutableMap.of()),
|
||||
null
|
||||
);
|
||||
|
||||
public final QuickfixType DEPRECATED_PROPERTY;
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
public AppPropertiesQuickFixes(QuickfixRegistry r) {
|
||||
DEPRECATED_PROPERTY = r.register("DEPRECATED_PROPERTY", (Object _params) -> {
|
||||
DeprecatedPropertyData params = gson.fromJson((JsonElement)_params, DeprecatedPropertyData.class);
|
||||
try {
|
||||
if (params.getRange() != null && params.getReplacement() != null) {
|
||||
WorkspaceEdit wsEdits = new WorkspaceEdit();
|
||||
wsEdits.setChanges(ImmutableMap.of(
|
||||
params.getUri(),
|
||||
ImmutableList.of(new TextEdit(params.getRange(), params.getReplacement()))
|
||||
));
|
||||
Position start = params.getRange().getStart();
|
||||
Position cursor = new Position(start.getLine(), start.getCharacter() + params.getReplacement().length());
|
||||
return new QuickfixEdit(wsEdits, new CursorMovement(params.getUri(), cursor));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
return NULL_FIX;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019 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.properties.quickfix;
|
||||
|
||||
import org.eclipse.lsp4j.Range;
|
||||
|
||||
/**
|
||||
* Deprecated property quick fix data
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class DeprecatedPropertyData {
|
||||
|
||||
private Range range;
|
||||
private String replacement;
|
||||
private String uri;
|
||||
|
||||
public DeprecatedPropertyData(String uri, Range range, String replacement) {
|
||||
this.setUri(uri);
|
||||
this.range = range;
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
public Range getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
public void setRange(Range range) {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public String getReplacement() {
|
||||
return replacement;
|
||||
}
|
||||
|
||||
public void setReplacement(String replacement) {
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
public String getUri() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
public void setUri(String uri) {
|
||||
this.uri = uri;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.properties.quickfix;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItemKind;
|
||||
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.util.Renderable;
|
||||
|
||||
public class ReplaceDeprecatedPropertyQuickfix implements ICompletionProposal {
|
||||
|
||||
// public static ProblemFixer FIXER = (context, problem, proposals) -> {
|
||||
// throw new UnsupportedOperationException("Not yet implemented");
|
||||
// PropertyInfo metadata = problem.getMetadata();
|
||||
// if (metadata!=null) {
|
||||
// String replacement = metadata.getDeprecationReplacement();
|
||||
// if (replacement!=null) {
|
||||
// //No need to check problem type... we only attach this fixer to problems of applicable type.
|
||||
// proposals.add(new ReplaceDeprecatedYamlQuickfix(context, problem));
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public CompletionItemKind getKind() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public DocumentEdits getTextEdit() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public String getDetail() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public Renderable getDocumentation() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public ScoreableProposal deemphasize(double howmuch) {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
// private final QuickfixContext context;
|
||||
// private final SpringPropertyProblem problem;
|
||||
//
|
||||
// private LazyProposalApplier applier = new LazyProposalApplier() {
|
||||
// protected ProposalApplier create() throws Exception {
|
||||
// String newName = problem.getMetadata().getDeprecationReplacement();
|
||||
// String oldName = problem.getPropertyName();
|
||||
// YamlPath newPath = YamlPath.fromProperty(newName);
|
||||
// YamlPath oldPath = YamlPath.fromProperty(oldName);
|
||||
// YamlPath prefix = newPath.commonPrefix(oldPath);
|
||||
// if (prefix.size()==newPath.size()-1 && newPath.size()==oldPath.size()) {
|
||||
// //only the last segment has changed. We can do a simple 'in-place' replace
|
||||
// // of just the change segment.
|
||||
// DocumentEdits edits = new DocumentEdits(context.getDocument());
|
||||
// edits.replace(problem.getOffset(), problem.getEnd(), newPath.getLastSegment().toPropString());
|
||||
// return edits;
|
||||
// }
|
||||
// YamlDocument doc = new YamlDocument(context.getDocument(), YamlStructureProvider.DEFAULT);
|
||||
// SNode problemNode = doc.getStructure().find(problem.getOffset());
|
||||
// if (problemNode.getNodeType()==SNodeType.KEY) {
|
||||
// SKeyNode problemKey = (SKeyNode) problemNode;
|
||||
// if (problemKey.isInKey(problem.getOffset())) {
|
||||
// YamlPathEdits edits = new YamlPathEdits(doc);
|
||||
//// print(doc, edits);
|
||||
// String valueText = problemKey.getValueWithRelativeIndent();
|
||||
// edits.deleteNode(problemKey);
|
||||
// int maxParentDeletions = oldPath.size() - prefix.size() - 1; // don't delete bits of the common prefix!
|
||||
// SChildBearingNode parent = problemNode.getParent();
|
||||
// while (maxParentDeletions>0 && parent!=null && parent.getChildren().size()==1) {
|
||||
// edits.deleteNode(parent);
|
||||
// parent = parent.getParent();
|
||||
// maxParentDeletions--;
|
||||
// }
|
||||
//// print(doc, edits);
|
||||
// SDocNode docRoot = problemNode.getDocNode(); //edits should stay within the same 'document' for yaml file that has multiple documents inside of it.
|
||||
// edits.createPath(docRoot, YamlPath.fromProperty(newName), valueText);
|
||||
//// print(doc, edits);
|
||||
// return edits;
|
||||
// }
|
||||
// }
|
||||
// //Not sure what to do... case not covered... so do nothing but tell the user.
|
||||
// context.getUI().error("Yaml file too complex",
|
||||
// "Sorry, but the yaml file is too complex for this quickfix. " +
|
||||
// "Please make the change manually."
|
||||
// );
|
||||
// return ProposalApplier.NULL;
|
||||
// }
|
||||
//
|
||||
//// private void print(YamlDocument doc, YamlPathEdits edits) throws Exception {
|
||||
//// Document workingCopy = new Document(doc.getDocument().get());
|
||||
//// edits.apply(workingCopy);
|
||||
//// System.out.println("==============");
|
||||
//// System.out.println(workingCopy.get());
|
||||
//// System.out.println("==============");
|
||||
//// }
|
||||
// };
|
||||
//
|
||||
// public ReplaceDeprecatedYamlQuickfix(QuickfixContext context, SpringPropertyProblem problem) {
|
||||
// this.context = context;
|
||||
// this.problem = problem;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void apply(IDocument doc) {
|
||||
// try {
|
||||
// applier.apply(doc);
|
||||
// } catch (Exception e) {
|
||||
// Log.log(e);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private String getReplacementProperty() {
|
||||
// return problem.getMetadata().getDeprecationReplacement();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Point getSelection(IDocument doc) {
|
||||
// try {
|
||||
// return applier.getSelection(doc);
|
||||
// } catch (Exception e) {
|
||||
// Log.log(e);
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getAdditionalProposalInfo() {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getDisplayString() {
|
||||
// return "Change to '"+getReplacementProperty()+"'";
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Image getImage() {
|
||||
// return JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public IContextInformation getContextInformation() {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014-2016 Pivotal, Inc.
|
||||
* Copyright (c) 2014, 2019 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
|
||||
@@ -18,6 +18,8 @@ import static org.springframework.ide.vscode.commons.util.StringUtil.commonPrefi
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.metadata.PropertyInfo;
|
||||
import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndex;
|
||||
import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
|
||||
@@ -25,12 +27,15 @@ import org.springframework.ide.vscode.boot.metadata.types.Type;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeParser;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtil;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider;
|
||||
import org.springframework.ide.vscode.boot.properties.quickfix.DeprecatedPropertyData;
|
||||
import org.springframework.ide.vscode.boot.properties.quickfix.AppPropertiesQuickFixes;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix.QuickfixData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixType;
|
||||
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.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParseException;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
@@ -53,6 +58,8 @@ import org.springframework.ide.vscode.java.properties.parser.PropertiesFileEscap
|
||||
*/
|
||||
public class SpringPropertiesReconcileEngine implements IReconcileEngine {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SpringPropertiesReconcileEngine.class);
|
||||
|
||||
/**
|
||||
* Regexp that matches a ',' surrounded by whitespace, including escaped whitespace / newlines
|
||||
*/
|
||||
@@ -67,10 +74,12 @@ public class SpringPropertiesReconcileEngine implements IReconcileEngine {
|
||||
private SpringPropertyIndexProvider fIndexProvider;
|
||||
private TypeUtilProvider typeUtilProvider;
|
||||
private Parser parser = new AntlrParser();
|
||||
private AppPropertiesQuickFixes quickFixes;
|
||||
|
||||
public SpringPropertiesReconcileEngine(SpringPropertyIndexProvider provider, TypeUtilProvider typeUtilProvider) {
|
||||
public SpringPropertiesReconcileEngine(SpringPropertyIndexProvider provider, TypeUtilProvider typeUtilProvider, AppPropertiesQuickFixes quickFixes) {
|
||||
this.fIndexProvider = provider;
|
||||
this.typeUtilProvider = typeUtilProvider;
|
||||
this.quickFixes = quickFixes;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -104,7 +113,7 @@ public class SpringPropertiesReconcileEngine implements IReconcileEngine {
|
||||
// it all with just passing around 'fullName' DocumentRegion. This may require changes
|
||||
// in PropertyNavigator (probably these changes are also for the better making it simpler as well)
|
||||
if (validProperty.isDeprecated()) {
|
||||
problemCollector.accept(problemDeprecated(propertyNameRegion, validProperty));
|
||||
problemCollector.accept(problemDeprecated(doc, propertyNameRegion, validProperty, quickFixes.DEPRECATED_PROPERTY));
|
||||
}
|
||||
int offset = validProperty.getId().length() + propertyNameRegion.getStart();
|
||||
PropertyNavigator navigator = new PropertyNavigator(doc, problemCollector, typeUtilProvider.getTypeUtil(doc), propertyNameRegion);
|
||||
@@ -119,17 +128,17 @@ public class SpringPropertiesReconcileEngine implements IReconcileEngine {
|
||||
problemCollector.accept(problemUnkownProperty(propertyNameRegion, similarEntry, validPrefix));
|
||||
} //end: validProperty==null
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
log.error("", e);
|
||||
}
|
||||
});
|
||||
} catch (Throwable e2) {
|
||||
Log.log(e2);
|
||||
log.error("", e2);
|
||||
} finally {
|
||||
problemCollector.endCollecting();
|
||||
}
|
||||
}
|
||||
|
||||
protected SpringPropertyProblem problemDeprecated(DocumentRegion region, PropertyInfo property) {
|
||||
protected SpringPropertyProblem problemDeprecated(IDocument doc, DocumentRegion region, PropertyInfo property, QuickfixType fixType) {
|
||||
SpringPropertyProblem p = problem(PROP_DEPRECATED,
|
||||
TypeUtil.deprecatedPropertyMessage(
|
||||
property.getId(), null,
|
||||
@@ -140,7 +149,15 @@ public class SpringPropertiesReconcileEngine implements IReconcileEngine {
|
||||
);
|
||||
p.setPropertyName(property.getId());
|
||||
p.setMetadata(property);
|
||||
// p.setProblemFixer(ReplaceDeprecatedPropertyQuickfix.FIXER);
|
||||
|
||||
try {
|
||||
p.addQuickfix(new QuickfixData<>(fixType,
|
||||
new DeprecatedPropertyData(doc.getUri(), doc.toRange(region), property.getDeprecationReplacement()),
|
||||
"Replace with `" + property.getDeprecationReplacement() + "`"));
|
||||
} catch (BadLocationException e) {
|
||||
log.error("", e);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -186,7 +203,7 @@ public class SpringPropertiesReconcileEngine implements IReconcileEngine {
|
||||
problems.accept(problem(ApplicationPropertiesProblemType.PROP_VALUE_TYPE_MISMATCH,
|
||||
ExceptionUtil.getMessage(e),
|
||||
e.getHighlightRegion(escapedValue)));
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
problems.accept(problem(ApplicationPropertiesProblemType.PROP_VALUE_TYPE_MISMATCH,
|
||||
"Expecting '"+typeUtil.niceTypeName(expectType)+"'",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* Copyright (c) 2016, 2019 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
|
||||
@@ -12,7 +12,6 @@
|
||||
package org.springframework.ide.vscode.boot.properties.reconcile;
|
||||
|
||||
import org.springframework.ide.vscode.boot.metadata.PropertyInfo;
|
||||
//import org.springframework.ide.vscode.commons.languageserver.quickfix.ProblemFixer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ProblemType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblemImpl;
|
||||
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
@@ -22,7 +21,6 @@ import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
|
||||
public class SpringPropertyProblem extends ReconcileProblemImpl {
|
||||
|
||||
private PropertyInfo property = null;
|
||||
// private ProblemFixer fixer;
|
||||
private String propertyName;
|
||||
|
||||
public SpringPropertyProblem(ProblemType type, String msg, int offset, int len) {
|
||||
@@ -44,10 +42,6 @@ public class SpringPropertyProblem extends ReconcileProblemImpl {
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
// public void setProblemFixer(ProblemFixer fixer) {
|
||||
// this.fixer = fixer;
|
||||
// }
|
||||
|
||||
public void setPropertyName(String name) {
|
||||
propertyName = name;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2019 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.yaml.quickfix;
|
||||
|
||||
import org.eclipse.lsp4j.TextEdit;
|
||||
import org.eclipse.lsp4j.WorkspaceEdit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.boot.properties.quickfix.DeprecatedPropertyData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixEdit.CursorMovement;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixRegistry;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
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.quickfix.YamlQuickfixes;
|
||||
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.SDocNode;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SKeyNode;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNodeType;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureProvider;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
/**
|
||||
* Boot YAML file properties quick fix code action handlers
|
||||
*
|
||||
* @author Alex Boyko
|
||||
*
|
||||
*/
|
||||
public class AppYamlQuickfixes {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AppYamlQuickfixes.class);
|
||||
|
||||
public final QuickfixType DEPRECATED_PROPERTY;
|
||||
|
||||
private static final QuickfixEdit NULL_FIX = new QuickfixEdit(
|
||||
new WorkspaceEdit(ImmutableMap.of()),
|
||||
null
|
||||
);
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
public AppYamlQuickfixes(QuickfixRegistry r, SimpleTextDocumentService textDocumentService, YamlStructureProvider structureProvider) {
|
||||
DEPRECATED_PROPERTY = r.register("DEPRECATED_YAML_PROPERTY", (Object _params) -> {
|
||||
DeprecatedPropertyData params = gson.fromJson((JsonElement)_params, DeprecatedPropertyData.class);
|
||||
try {
|
||||
TextDocument _doc = textDocumentService.getDocument(params.getUri());
|
||||
if (_doc!=null) {
|
||||
YamlDocument doc = new YamlDocument(_doc, structureProvider);
|
||||
SNode root = doc.getStructure();
|
||||
int offset = _doc.toOffset(params.getRange().getStart());
|
||||
SNode node = root.find(offset);
|
||||
if (node != null) {
|
||||
// Drop the doc root
|
||||
YamlPath oldPath = node.getPath().dropFirst(1);
|
||||
YamlPath newPath = YamlPath.fromProperty(params.getReplacement());
|
||||
YamlPath prefix = newPath.commonPrefix(oldPath);
|
||||
if (prefix.size()==newPath.size()-1 && newPath.size()==oldPath.size()) {
|
||||
//only the last segment has changed. We can do a simple 'in-place' replace
|
||||
// of just the change segment.
|
||||
WorkspaceEdit wsEdits = new WorkspaceEdit();
|
||||
String replacement = newPath.getLastSegment().toPropString();
|
||||
wsEdits.setChanges(ImmutableMap.of(
|
||||
params.getUri(),
|
||||
ImmutableList.of(new TextEdit(params.getRange(), replacement))
|
||||
));
|
||||
return new QuickfixEdit(wsEdits, new CursorMovement(params.getUri(), _doc.toPosition(node.getNodeEnd())));
|
||||
}
|
||||
if (node.getNodeType()==SNodeType.KEY) {
|
||||
SKeyNode problemKey = (SKeyNode) node;
|
||||
if (problemKey.isInKey(offset)) {
|
||||
YamlPathEdits edits = new YamlPathEdits(doc);
|
||||
String valueText = problemKey.getValueWithRelativeIndent();
|
||||
edits.deleteNode(problemKey);
|
||||
int maxParentDeletions = oldPath.size() - prefix.size() - 1; // don't delete bits of the common prefix!
|
||||
SChildBearingNode parent = node.getParent();
|
||||
while (maxParentDeletions>0 && parent!=null && parent.getChildren().size()==1) {
|
||||
edits.deleteNode(parent);
|
||||
parent = parent.getParent();
|
||||
maxParentDeletions--;
|
||||
}
|
||||
SDocNode docRoot = node.getDocNode(); //edits should stay within the same 'document' for yaml file that has multiple documents inside of it.
|
||||
edits.createPath(docRoot, YamlPath.fromProperty(params.getReplacement()), valueText);
|
||||
|
||||
return YamlQuickfixes.createReplacementQuickfic(_doc, edits);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
}
|
||||
return NULL_FIX;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* 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.yaml.quickfix;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItemKind;
|
||||
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.util.Renderable;
|
||||
|
||||
public class ReplaceDeprecatedYamlQuickfix implements ICompletionProposal {
|
||||
|
||||
// public static ProblemFixer FIXER = (context, problem, proposals) -> {
|
||||
// throw new UnsupportedOperationException("Not yet implemented");
|
||||
// PropertyInfo metadata = problem.getMetadata();
|
||||
// if (metadata!=null) {
|
||||
// String replacement = metadata.getDeprecationReplacement();
|
||||
// if (replacement!=null) {
|
||||
// //No need to check problem type... we only attach this fixer to problems of applicable type.
|
||||
// proposals.add(new ReplaceDeprecatedYamlQuickfix(context, problem));
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public CompletionItemKind getKind() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public DocumentEdits getTextEdit() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public String getDetail() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public Renderable getDocumentation() {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
@Override
|
||||
public ScoreableProposal deemphasize(double howmuch) {
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
|
||||
// private final QuickfixContext context;
|
||||
// private final SpringPropertyProblem problem;
|
||||
//
|
||||
// private LazyProposalApplier applier = new LazyProposalApplier() {
|
||||
// protected ProposalApplier create() throws Exception {
|
||||
// String newName = problem.getMetadata().getDeprecationReplacement();
|
||||
// String oldName = problem.getPropertyName();
|
||||
// YamlPath newPath = YamlPath.fromProperty(newName);
|
||||
// YamlPath oldPath = YamlPath.fromProperty(oldName);
|
||||
// YamlPath prefix = newPath.commonPrefix(oldPath);
|
||||
// if (prefix.size()==newPath.size()-1 && newPath.size()==oldPath.size()) {
|
||||
// //only the last segment has changed. We can do a simple 'in-place' replace
|
||||
// // of just the change segment.
|
||||
// DocumentEdits edits = new DocumentEdits(context.getDocument());
|
||||
// edits.replace(problem.getOffset(), problem.getEnd(), newPath.getLastSegment().toPropString());
|
||||
// return edits;
|
||||
// }
|
||||
// YamlDocument doc = new YamlDocument(context.getDocument(), YamlStructureProvider.DEFAULT);
|
||||
// SNode problemNode = doc.getStructure().find(problem.getOffset());
|
||||
// if (problemNode.getNodeType()==SNodeType.KEY) {
|
||||
// SKeyNode problemKey = (SKeyNode) problemNode;
|
||||
// if (problemKey.isInKey(problem.getOffset())) {
|
||||
// YamlPathEdits edits = new YamlPathEdits(doc);
|
||||
//// print(doc, edits);
|
||||
// String valueText = problemKey.getValueWithRelativeIndent();
|
||||
// edits.deleteNode(problemKey);
|
||||
// int maxParentDeletions = oldPath.size() - prefix.size() - 1; // don't delete bits of the common prefix!
|
||||
// SChildBearingNode parent = problemNode.getParent();
|
||||
// while (maxParentDeletions>0 && parent!=null && parent.getChildren().size()==1) {
|
||||
// edits.deleteNode(parent);
|
||||
// parent = parent.getParent();
|
||||
// maxParentDeletions--;
|
||||
// }
|
||||
//// print(doc, edits);
|
||||
// SDocNode docRoot = problemNode.getDocNode(); //edits should stay within the same 'document' for yaml file that has multiple documents inside of it.
|
||||
// edits.createPath(docRoot, YamlPath.fromProperty(newName), valueText);
|
||||
//// print(doc, edits);
|
||||
// return edits;
|
||||
// }
|
||||
// }
|
||||
// //Not sure what to do... case not covered... so do nothing but tell the user.
|
||||
// context.getUI().error("Yaml file too complex",
|
||||
// "Sorry, but the yaml file is too complex for this quickfix. " +
|
||||
// "Please make the change manually."
|
||||
// );
|
||||
// return ProposalApplier.NULL;
|
||||
// }
|
||||
//
|
||||
//// private void print(YamlDocument doc, YamlPathEdits edits) throws Exception {
|
||||
//// Document workingCopy = new Document(doc.getDocument().get());
|
||||
//// edits.apply(workingCopy);
|
||||
//// System.out.println("==============");
|
||||
//// System.out.println(workingCopy.get());
|
||||
//// System.out.println("==============");
|
||||
//// }
|
||||
// };
|
||||
//
|
||||
// public ReplaceDeprecatedYamlQuickfix(QuickfixContext context, SpringPropertyProblem problem) {
|
||||
// this.context = context;
|
||||
// this.problem = problem;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void apply(IDocument doc) {
|
||||
// try {
|
||||
// applier.apply(doc);
|
||||
// } catch (Exception e) {
|
||||
// Log.log(e);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private String getReplacementProperty() {
|
||||
// return problem.getMetadata().getDeprecationReplacement();
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Point getSelection(IDocument doc) {
|
||||
// try {
|
||||
// return applier.getSelection(doc);
|
||||
// } catch (Exception e) {
|
||||
// Log.log(e);
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getAdditionalProposalInfo() {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public String getDisplayString() {
|
||||
// return "Change to '"+getReplacementProperty()+"'";
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Image getImage() {
|
||||
// return JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public IContextInformation getContextInformation() {
|
||||
// return null;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* Copyright (c) 2016, 2019 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
|
||||
@@ -22,6 +22,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.lsp4j.Position;
|
||||
import org.eclipse.lsp4j.Range;
|
||||
import org.springframework.ide.vscode.boot.metadata.IndexNavigator;
|
||||
import org.springframework.ide.vscode.boot.metadata.PropertyInfo;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.Type;
|
||||
@@ -30,6 +32,10 @@ import org.springframework.ide.vscode.boot.metadata.types.TypeUtil;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtil.BeanPropertyNameMode;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtil.EnumCaseMode;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypedProperty;
|
||||
import org.springframework.ide.vscode.boot.properties.quickfix.DeprecatedPropertyData;
|
||||
import org.springframework.ide.vscode.boot.yaml.quickfix.AppYamlQuickfixes;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.Quickfix.QuickfixData;
|
||||
import org.springframework.ide.vscode.commons.languageserver.quickfix.QuickfixType;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
@@ -58,11 +64,13 @@ public class ApplicationYamlASTReconciler implements YamlASTReconciler {
|
||||
private final IProblemCollector problems;
|
||||
private final TypeUtil typeUtil;
|
||||
private final IndexNavigator nav;
|
||||
private AppYamlQuickfixes quickFixes;
|
||||
|
||||
public ApplicationYamlASTReconciler(IProblemCollector problems, IndexNavigator nav, TypeUtil typeUtil) {
|
||||
public ApplicationYamlASTReconciler(IProblemCollector problems, IndexNavigator nav, TypeUtil typeUtil, AppYamlQuickfixes quickFixes) {
|
||||
this.problems = problems;
|
||||
this.typeUtil = typeUtil;
|
||||
this.nav = nav;
|
||||
this.quickFixes = quickFixes;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -155,7 +163,7 @@ public class ApplicationYamlASTReconciler implements YamlASTReconciler {
|
||||
} else if (match!=null) {
|
||||
Type type = TypeParser.parse(match.getType());
|
||||
if (match.isDeprecated()) {
|
||||
deprecatedProperty(match, keyNode);
|
||||
deprecatedProperty(root.getDocument().getUri(), match, keyNode, quickFixes.DEPRECATED_PROPERTY);
|
||||
}
|
||||
reconcile(root, entry.getValueNode(), type);
|
||||
} else if (extension!=null) {
|
||||
@@ -241,7 +249,7 @@ public class ApplicationYamlASTReconciler implements YamlASTReconciler {
|
||||
TypedProperty typedProperty = props.get(key);
|
||||
if (typedProperty!=null) {
|
||||
if (typedProperty.isDeprecated()) {
|
||||
deprecatedProperty(type, typedProperty, keyNode);
|
||||
deprecatedProperty(root.getDocument().getUri(), type, typedProperty, keyNode, quickFixes.DEPRECATED_PROPERTY);
|
||||
}
|
||||
reconcile(root, valNode, typedProperty.getType());
|
||||
}
|
||||
@@ -363,24 +371,28 @@ public class ApplicationYamlASTReconciler implements YamlASTReconciler {
|
||||
problems.accept(problem(problemType, node, "Expecting a '"+typeUtil.niceTypeName(type)+"' but got "+describe(node)));
|
||||
}
|
||||
|
||||
private void deprecatedProperty(PropertyInfo property, Node keyNode) {
|
||||
SpringPropertyProblem problem = deprecatedPropertyProblem(property.getId(), null, keyNode,
|
||||
property.getDeprecationReplacement(), property.getDeprecationReason());
|
||||
private void deprecatedProperty(String docUri, PropertyInfo property, Node keyNode, QuickfixType fixType) {
|
||||
SpringPropertyProblem problem = deprecatedPropertyProblem(docUri, property.getId(), null, keyNode,
|
||||
property.getDeprecationReplacement(), property.getDeprecationReason(), fixType);
|
||||
problem.setMetadata(property);
|
||||
//problem.setProblemFixer(ReplaceDeprecatedYamlQuickfix.FIXER);
|
||||
problems.accept(problem);
|
||||
}
|
||||
|
||||
private void deprecatedProperty(Type contextType, TypedProperty property, Node keyNode) {
|
||||
SpringPropertyProblem problem = deprecatedPropertyProblem(property.getName(), typeUtil.niceTypeName(contextType),
|
||||
keyNode, property.getDeprecationReplacement(), property.getDeprecationReason());
|
||||
private void deprecatedProperty(String docUri, Type contextType, TypedProperty property, Node keyNode, QuickfixType fixType) {
|
||||
SpringPropertyProblem problem = deprecatedPropertyProblem(docUri, property.getName(), typeUtil.niceTypeName(contextType),
|
||||
keyNode, property.getDeprecationReplacement(), property.getDeprecationReason(), fixType);
|
||||
problems.accept(problem);
|
||||
}
|
||||
|
||||
protected SpringPropertyProblem deprecatedPropertyProblem(String name, String contextType, Node keyNode,
|
||||
String replace, String reason) {
|
||||
protected SpringPropertyProblem deprecatedPropertyProblem(String docUri, String name, String contextType, Node keyNode,
|
||||
String replace, String reason, QuickfixType fixType) {
|
||||
SpringPropertyProblem problem = problem(YAML_DEPRECATED, keyNode, TypeUtil.deprecatedPropertyMessage(name, contextType, replace, reason));
|
||||
problem.setPropertyName(name);
|
||||
Range range = new Range(new Position(keyNode.getStartMark().getLine(), keyNode.getStartMark().getColumn()),
|
||||
new Position(keyNode.getEndMark().getLine(), keyNode.getEndMark().getColumn()));
|
||||
|
||||
problem.addQuickfix(new QuickfixData<>(fixType, new DeprecatedPropertyData(docUri, range, replace), "Replace with `" + replace + "`"));
|
||||
return problem;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2016 Pivotal, Inc.
|
||||
* Copyright (c) 2015, 2019 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
|
||||
@@ -16,6 +16,7 @@ import org.springframework.ide.vscode.boot.metadata.IndexNavigator;
|
||||
import org.springframework.ide.vscode.boot.metadata.PropertyInfo;
|
||||
import org.springframework.ide.vscode.boot.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.boot.metadata.types.TypeUtilProvider;
|
||||
import org.springframework.ide.vscode.boot.yaml.quickfix.AppYamlQuickfixes;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.ReconcileProblem;
|
||||
import org.springframework.ide.vscode.commons.util.FuzzyMap;
|
||||
@@ -28,18 +29,21 @@ public class ApplicationYamlReconcileEngine extends YamlReconcileEngine {
|
||||
|
||||
private SpringPropertyIndexProvider indexProvider;
|
||||
private TypeUtilProvider typeUtilProvider;
|
||||
private AppYamlQuickfixes quickFixes;
|
||||
|
||||
public ApplicationYamlReconcileEngine(YamlASTProvider astProvider, SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider) {
|
||||
public ApplicationYamlReconcileEngine(YamlASTProvider astProvider, SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, AppYamlQuickfixes quickFixes) {
|
||||
super(astProvider);
|
||||
this.indexProvider = indexProvider;
|
||||
this.typeUtilProvider = typeUtilProvider;
|
||||
this.quickFixes = quickFixes;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected YamlASTReconciler getASTReconciler(IDocument doc, IProblemCollector problemCollector) {
|
||||
FuzzyMap<PropertyInfo> index = indexProvider.getIndex(doc);
|
||||
if (index!=null && !index.isEmpty()) {
|
||||
IndexNavigator nav = IndexNavigator.with(index);
|
||||
return new ApplicationYamlASTReconciler(problemCollector, nav, typeUtilProvider.getTypeUtil(doc));
|
||||
return new ApplicationYamlASTReconciler(problemCollector, nav, typeUtilProvider.getTypeUtil(doc), quickFixes);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016-2017 Pivotal, Inc.
|
||||
* Copyright (c) 2016, 2019 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
|
||||
@@ -18,7 +18,6 @@ import org.springframework.ide.vscode.commons.languageserver.reconcile.Reconcile
|
||||
public class SpringPropertyProblem extends ReconcileProblemImpl {
|
||||
|
||||
private PropertyInfo property = null;
|
||||
// private ProblemFixer fixer;
|
||||
private String propertyName;
|
||||
|
||||
public SpringPropertyProblem(ProblemType type, String msg, int offset, int len) {
|
||||
@@ -33,10 +32,6 @@ public class SpringPropertyProblem extends ReconcileProblemImpl {
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
// public void setProblemFixer(ProblemFixer fixer) {
|
||||
// this.fixer = fixer;
|
||||
// }
|
||||
|
||||
public void setPropertyName(String name) {
|
||||
propertyName = name;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import java.util.List;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItem;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -42,6 +41,7 @@ import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IType;
|
||||
import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.CodeAction;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
import org.springframework.ide.vscode.project.harness.ProjectsHarness.ProjectCustomizer;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
@@ -997,7 +997,7 @@ public class ApplicationPropertiesEditorTest extends AbstractPropsEditorTest {
|
||||
editor.assertHoverText("path", "**Deprecated!**");
|
||||
}
|
||||
|
||||
@Ignore @Test public void testDeprecatedPropertyQuickfix() throws Exception {
|
||||
@Test public void testDeprecatedPropertyQuickfix() throws Exception {
|
||||
data("error.path", "java.lang.String", null, "Path of the error controller.");
|
||||
deprecate("error.path", "server.error.path", null);
|
||||
|
||||
@@ -1007,8 +1007,8 @@ public class ApplicationPropertiesEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("error.path");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'server.error.path'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `server.error.path`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"server.error.path<*>=foo\n"
|
||||
|
||||
@@ -20,7 +20,6 @@ import static org.springframework.ide.vscode.languageserver.testharness.Editor.I
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.eclipse.lsp4j.CompletionItem;
|
||||
import org.eclipse.lsp4j.Diagnostic;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
@@ -39,6 +38,7 @@ import org.springframework.ide.vscode.commons.maven.java.MavenJavaProject;
|
||||
import org.springframework.ide.vscode.commons.util.RunnableWithException;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.CodeAction;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@@ -2767,7 +2767,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
assertCompletionDetailsWithDeprecation("foo:\n nam<*>", "alt-name", "String", null, Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Ignore @Test public void testDeprecatedPropertyQuickfixSimple() throws Exception {
|
||||
@Test public void testDeprecatedPropertyQuickfixSimple() throws Exception {
|
||||
//A simple case for starters. The path edits aren't too complicated since there's
|
||||
//just the one property in the file and only the last part of the 'path' changes.
|
||||
//So this is a simple 'in-place' edit.
|
||||
@@ -2783,12 +2783,12 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("old-name");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.new-name'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `my.new-name`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"my:\n"+
|
||||
" new-name: foo\n"
|
||||
" new-name: foo<*>\n"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2801,12 +2801,12 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("old-name");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.new-name'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `my.new-name`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"my:\n"+
|
||||
" new-name: foo\n"+
|
||||
" new-name: foo<*>\n"+
|
||||
"your: stuff"
|
||||
);
|
||||
}
|
||||
@@ -2820,18 +2820,18 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("old-name");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.new-name'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `my.new-name`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"my:\n"+
|
||||
" new-name: foo\n" +
|
||||
" new-name: foo<*>\n" +
|
||||
" other: bar\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore @Test public void testDeprecatedPropertyQuickfixMovingValue() throws Exception {
|
||||
@Test public void testDeprecatedPropertyQuickfixMovingValue() throws Exception {
|
||||
data("my.old-name", "java.lang.String", null, "Old and deprecated name");
|
||||
deprecate("my.old-name", "your.new-name", null);
|
||||
|
||||
@@ -2853,15 +2853,15 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("pieces");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.path.with.many.pieces'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `my.path.with.many.pieces`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"my:\n" +
|
||||
" path:\n"+
|
||||
" with:\n"+
|
||||
" many:\n"+
|
||||
" pieces: foo"
|
||||
" pieces: foo<*>"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2878,8 +2878,8 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("pieces");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.path.with.many.pieces'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `my.path.with.many.pieces`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"my:\n" +
|
||||
@@ -2891,7 +2891,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
" path:\n"+
|
||||
" with:\n"+
|
||||
" many:\n"+
|
||||
" pieces: foo"
|
||||
" pieces: foo<*>"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2903,13 +2903,13 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("stuff");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.for-sale.stuff'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `my.for-sale.stuff`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"my:\n" +
|
||||
" for-sale:\n"+
|
||||
" stuff: foo"
|
||||
" stuff: foo<*>"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2921,12 +2921,12 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("old-name");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'your.new-name'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `your.new-name`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"your:\n"+
|
||||
" new-name: foo"
|
||||
" new-name: foo<*>"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2940,13 +2940,13 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("old-name");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'your.new-name'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `your.new-name`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"your:\n"+
|
||||
" goodies: nice\n"+
|
||||
" new-name: foo"
|
||||
" new-name: foo<*>"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2961,20 +2961,20 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
|
||||
Diagnostic problem = editor.assertProblem("old-name");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'your.new-name'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `your.new-name`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"your:\n"+
|
||||
" goodies: nice\n"+
|
||||
" new-name: foo\n" +
|
||||
" new-name: foo<*>\n" +
|
||||
"my:\n" +
|
||||
" other: stuff"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Ignore @Test public void testDeprecatedPropertyQuickfixMovingIndentedValue() throws Exception {
|
||||
@Test public void testDeprecatedPropertyQuickfixMovingIndentedValue() throws Exception {
|
||||
data("my.old-name", "java.lang.String", null, "Old and deprecated name");
|
||||
deprecate("my.old-name", "your.new-name", null); //same indent level
|
||||
|
||||
@@ -3000,8 +3000,8 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
" stuff: goes here\n"
|
||||
);
|
||||
Diagnostic problem = editor.assertProblem("pieces");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'short.path'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `short.path`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"short:\n"+
|
||||
@@ -3009,7 +3009,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
" path: >\n" +
|
||||
" foo spread over\n"+
|
||||
" several lines\n" +
|
||||
" of text\n"
|
||||
" of text<*>\n"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3025,8 +3025,8 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
" of text\n"
|
||||
);
|
||||
Diagnostic problem = editor.assertProblem("stuff");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'my.long.path.with.many.pieces'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `my.long.path.with.many.pieces`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"my:\n" +
|
||||
@@ -3038,7 +3038,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
" pieces: >\n" +
|
||||
" foo spread over\n"+
|
||||
" several lines\n" +
|
||||
" of text"
|
||||
" of text<*>"
|
||||
);
|
||||
}
|
||||
{
|
||||
@@ -3060,8 +3060,8 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
" stuff: goes here\n"
|
||||
);
|
||||
Diagnostic problem = editor.assertProblem("pieces");
|
||||
CompletionItem fix = editor.assertFirstQuickfix(problem, "Change to 'short.path'");
|
||||
editor.apply(fix);
|
||||
CodeAction fix = editor.assertFirstQuickfix(problem, "Replace with `short.path`");
|
||||
fix.perform();
|
||||
editor.assertText(
|
||||
"# a comment\n"+
|
||||
"short:\n"+
|
||||
@@ -3072,7 +3072,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
" #confusing\n" +
|
||||
" - several lines\n" +
|
||||
" #comments\n" +
|
||||
" - of text\n"
|
||||
" - of text<*>\n"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user