PT 131351003 - Added hover support for property keys
Also enabled JUnits to test hover support for property keys.
This commit is contained in:
@@ -1,4 +1,14 @@
|
||||
package org.springframework.ide.vscode.application.properties.hover;
|
||||
/*******************************************************************************
|
||||
* 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.application.properties.metadata.hover;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -16,7 +26,7 @@ public abstract class AbstractPropertyRenderableProvider {
|
||||
*/
|
||||
private static final String ACTION_HOST = "action";
|
||||
|
||||
Renderable getRenderable() {
|
||||
public Renderable getRenderable() {
|
||||
return new Renderable() {
|
||||
|
||||
@Override
|
||||
@@ -1,4 +1,14 @@
|
||||
package org.springframework.ide.vscode.application.properties.hover;
|
||||
/*******************************************************************************
|
||||
* 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.application.properties.metadata.hover;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -5,8 +5,8 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Deprecated, this class is here to make porting old STS code easier. Code should
|
||||
* avoid using this as much as possible and replaces calls to this by using Slf4J loggers
|
||||
* directly.
|
||||
* avoid using this as much as possible and replaces calls to this by using
|
||||
* {@link java.util.logging.Logger} directly
|
||||
*/
|
||||
@Deprecated
|
||||
public class Log {
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.completion;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.PrefixFinder;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SDocNode;
|
||||
@@ -94,17 +96,17 @@ public abstract class AbstractYamlAssistContext implements YamlAssistContext {
|
||||
return CompletionFactory.DEFAULT;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public HoverInfo getHoverInfo() {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public HoverInfo getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
// //By default we don't provide value-specific hover, so just show the same hover
|
||||
// // as the assistContext the value is in. This is likely more interesting than showing nothing at all.
|
||||
// return getHoverInfo();
|
||||
// }
|
||||
@Override
|
||||
public Renderable getHoverInfo() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
//By default we don't provide value-specific hover, so just show the same hover
|
||||
// as the assistContext the value is in. This is likely more interesting than showing nothing at all.
|
||||
return getHoverInfo();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.util.Optional;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.PropertyInfo;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndex;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.hints.StsValueHint;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.hover.PropertyRenderableProvider;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.Type;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil.EnumCaseMode;
|
||||
|
||||
@@ -3,22 +3,32 @@ package org.springframework.ide.vscode.application.yaml;
|
||||
import org.eclipse.lsp4j.CompletionOptions;
|
||||
import org.eclipse.lsp4j.ServerCapabilities;
|
||||
import org.eclipse.lsp4j.TextDocumentSyncKind;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.PropertyInfo;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.completions.PropertyCompletionFactory;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.completions.RelaxedNameConfig;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtilProvider;
|
||||
import org.springframework.ide.vscode.application.yaml.completions.ApplicationYamlCompletionEngine;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.application.yaml.completions.ApplicationYamlAssistContext;
|
||||
import org.springframework.ide.vscode.application.yaml.completions.ApplicationYamlStructureProvider;
|
||||
import org.springframework.ide.vscode.application.yaml.reconcile.ApplicationYamlReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.VscodeCompletionEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.HoverInfoProvider;
|
||||
import org.springframework.ide.vscode.commons.languageserver.hover.VscodeHoverEngineAdapter;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.reconcile.IReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlASTProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlParser;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.YamlAssistContext;
|
||||
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.structure.YamlDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureProvider;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
public class ApplicationYamlLanguageServer extends SimpleLanguageServer {
|
||||
@@ -28,6 +38,8 @@ public class ApplicationYamlLanguageServer extends SimpleLanguageServer {
|
||||
private SpringPropertyIndexProvider indexProvider;
|
||||
private TypeUtilProvider typeUtilProvider;
|
||||
private VscodeCompletionEngineAdapter completionEngine;
|
||||
private VscodeHoverEngineAdapter hoverEngine;
|
||||
|
||||
|
||||
public ApplicationYamlLanguageServer(SpringPropertyIndexProvider indexProvider, TypeUtilProvider typeUtilProvider, JavaProjectFinder javaProjectFinder) {
|
||||
this.indexProvider = indexProvider;
|
||||
@@ -51,16 +63,27 @@ public class ApplicationYamlLanguageServer extends SimpleLanguageServer {
|
||||
// }
|
||||
// });
|
||||
|
||||
YamlCompletionEngine yamlCompletionEngine = ApplicationYamlCompletionEngine.create(
|
||||
indexProvider,
|
||||
javaProjectFinder,
|
||||
ApplicationYamlStructureProvider.INSTANCE,
|
||||
typeUtilProvider,
|
||||
RelaxedNameConfig.COMPLETION_DEFAULTS
|
||||
);
|
||||
YamlStructureProvider structureProvider = ApplicationYamlStructureProvider.INSTANCE;
|
||||
RelaxedNameConfig relaxedNameConfig = RelaxedNameConfig.COMPLETION_DEFAULTS;
|
||||
|
||||
final PropertyCompletionFactory completionFactory = new PropertyCompletionFactory(javaProjectFinder);
|
||||
YamlAssistContextProvider contextProvider = new YamlAssistContextProvider() {
|
||||
@Override
|
||||
public YamlAssistContext getGlobalAssistContext(YamlDocument ydoc) {
|
||||
IDocument doc = ydoc.getDocument();
|
||||
FuzzyMap<PropertyInfo> index = indexProvider.getIndex(doc);
|
||||
return ApplicationYamlAssistContext.global(index, completionFactory, typeUtilProvider.getTypeUtil(doc), relaxedNameConfig);
|
||||
}
|
||||
};
|
||||
YamlCompletionEngine yamlCompletionEngine = new YamlCompletionEngine(structureProvider, contextProvider);
|
||||
|
||||
completionEngine = new VscodeCompletionEngineAdapter(this, yamlCompletionEngine);
|
||||
documents.onCompletion(completionEngine::getCompletions);
|
||||
documents.onCompletionResolve(completionEngine::resolveCompletion);
|
||||
|
||||
HoverInfoProvider infoProvider = new YamlHoverInfoProvider(parser, structureProvider, contextProvider);
|
||||
hoverEngine = new VscodeHoverEngineAdapter(this, infoProvider);
|
||||
documents.onHover(hoverEngine::getHover);
|
||||
}
|
||||
|
||||
public void setMaxCompletionsNumber(int number) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.springframework.ide.vscode.application.properties.metadata.completion
|
||||
import org.springframework.ide.vscode.application.properties.metadata.hints.HintProvider;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.hints.StsValueHint;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.hints.ValueHintHoverInfo;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.hover.PropertyRenderableProvider;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.Type;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypeParser;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil;
|
||||
@@ -36,7 +37,6 @@ import org.springframework.ide.vscode.application.properties.metadata.util.Fuzzy
|
||||
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.LazyProposalApplier;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ProposalApplier;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
|
||||
import org.springframework.ide.vscode.commons.util.CollectionUtil;
|
||||
@@ -280,27 +280,27 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public HoverInfo getValueHoverInfo(YamlDocument doc, DocumentRegion valueRegion) {
|
||||
// String value = valueRegion.toString();
|
||||
//
|
||||
// if (TypeUtil.isClass(type)) {
|
||||
// //Special case. We want hovers/hyperlinks even if the class is not a valid hint (as long as it is a class)
|
||||
// StsValueHint hint = StsValueHint.className(value.toString(), typeUtil);
|
||||
// if (hint!=null) {
|
||||
// return new ValueHintHoverInfo(hint);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// Collection<StsValueHint> hints = getHintValues(value, doc, valueRegion.getEnd(), EnumCaseMode.ALIASED);
|
||||
// //The hints where found by fuzzy match so they may not actually match exactly!
|
||||
// for (StsValueHint h : hints) {
|
||||
// if (value.equals(h.getValue())) {
|
||||
// return new ValueHintHoverInfo(h);
|
||||
// }
|
||||
// }
|
||||
// return super.getValueHoverInfo(doc, valueRegion);
|
||||
// }
|
||||
@Override
|
||||
public Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion valueRegion) {
|
||||
String value = valueRegion.toString();
|
||||
|
||||
if (TypeUtil.isClass(type)) {
|
||||
//Special case. We want hovers/hyperlinks even if the class is not a valid hint (as long as it is a class)
|
||||
StsValueHint hint = StsValueHint.className(value.toString(), typeUtil);
|
||||
if (hint!=null) {
|
||||
return hint.getDescription();
|
||||
}
|
||||
}
|
||||
|
||||
Collection<StsValueHint> hints = getHintValues(value, doc, valueRegion.getEnd(), EnumCaseMode.ALIASED);
|
||||
//The hints where found by fuzzy match so they may not actually match exactly!
|
||||
for (StsValueHint h : hints) {
|
||||
if (value.equals(h.getValue())) {
|
||||
return h.getDescription();
|
||||
}
|
||||
}
|
||||
return getHoverInfo();
|
||||
}
|
||||
|
||||
protected Collection<StsValueHint> getHintValues(
|
||||
String query,
|
||||
@@ -357,17 +357,17 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
}
|
||||
|
||||
|
||||
// @Override
|
||||
// public HoverInfo getHoverInfo() {
|
||||
// if (parent instanceof IndexContext) {
|
||||
// //this context is in fact an 'alias' of its parent, representing the
|
||||
// // point in the context hierarchy where a we transition from navigating
|
||||
// // the index to navigating type/bean properties
|
||||
// return parent.getHoverInfo();
|
||||
// } else {
|
||||
// return new JavaTypeNavigationHoverInfo(contextPath.toPropString(), contextPath.getBeanPropertyName(), parent.getType(), getType(), typeUtil);
|
||||
// }
|
||||
// }
|
||||
@Override
|
||||
public Renderable getHoverInfo() {
|
||||
if (parent instanceof IndexContext) {
|
||||
//this context is in fact an 'alias' of its parent, representing the
|
||||
// point in the context hierarchy where a we transition from navigating
|
||||
// the index to navigating type/bean properties
|
||||
return parent.getHoverInfo();
|
||||
} else {
|
||||
return new JavaTypeNavigationHoverInfo(contextPath.toPropString(), contextPath.getBeanPropertyName(), parent.getType(), getType(), typeUtil).getRenderable();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Type getType() {
|
||||
@@ -381,18 +381,6 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getValueHoverInfo(YamlDocument doc, DocumentRegion documentRegion) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Renderable getHoverInfo() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class IndexContext extends ApplicationYamlAssistContext {
|
||||
@@ -505,10 +493,13 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
|
||||
@Override
|
||||
public Renderable getHoverInfo() {
|
||||
// TODO Auto-generated method stub
|
||||
PropertyInfo prop = indexNav.getExactMatch();
|
||||
if (prop!=null) {
|
||||
return new PropertyRenderableProvider(typeUtil.getJavaProject(), prop).getRenderable();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Renderable getHoverInfo(YamlPathSegment lastSegment) {
|
||||
// TODO Auto-generated method stub
|
||||
@@ -520,22 +511,12 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public HoverInfo getHoverInfo() {
|
||||
// PropertyInfo prop = indexNav.getExactMatch();
|
||||
// if (prop!=null) {
|
||||
// return new SpringPropertyHoverInfo(typeUtil.getJavaProject(), prop);
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
}
|
||||
|
||||
// public abstract HoverInfo getHoverInfo();
|
||||
// public HoverInfo getHoverInfo(YamlPathSegment s) {
|
||||
// //ApplicationYamlAssistContext implements getHoverInfo directly. so this is not needed.
|
||||
// return null;
|
||||
// }
|
||||
public Renderable getHoverInfo(YamlPathSegment s) {
|
||||
//ApplicationYamlAssistContext implements getHoverInfo directly. so this is not needed.
|
||||
return null;
|
||||
}
|
||||
|
||||
public static YamlAssistContext global(final FuzzyMap<PropertyInfo> index, final PropertyCompletionFactory completionFactory, final TypeUtil typeUtil, final RelaxedNameConfig conf) {
|
||||
return new TopLevelAssistContext() {
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.application.yaml.completions;
|
||||
|
||||
import org.springframework.ide.vscode.application.properties.metadata.PropertyInfo;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.SpringPropertyIndexProvider;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.completions.PropertyCompletionFactory;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.completions.RelaxedNameConfig;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtilProvider;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.util.FuzzyMap;
|
||||
import org.springframework.ide.vscode.commons.languageserver.java.JavaProjectFinder;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.YamlAssistContext;
|
||||
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.structure.YamlDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureProvider;
|
||||
|
||||
/**
|
||||
* @author Kris De Volder
|
||||
*/
|
||||
public class ApplicationYamlCompletionEngine {
|
||||
public static YamlCompletionEngine create(
|
||||
final SpringPropertyIndexProvider indexProvider,
|
||||
final JavaProjectFinder documentContextFinder,
|
||||
final YamlStructureProvider structureProvider,
|
||||
final TypeUtilProvider typeUtilProvider,
|
||||
final RelaxedNameConfig conf
|
||||
) {
|
||||
final PropertyCompletionFactory completionFactory = new PropertyCompletionFactory(documentContextFinder);
|
||||
YamlAssistContextProvider contextProvider = new YamlAssistContextProvider() {
|
||||
@Override
|
||||
public YamlAssistContext getGlobalAssistContext(YamlDocument ydoc) {
|
||||
IDocument doc = ydoc.getDocument();
|
||||
FuzzyMap<PropertyInfo> index = indexProvider.getIndex(doc);
|
||||
return ApplicationYamlAssistContext.global(index, completionFactory, typeUtilProvider.getTypeUtil(doc), conf);
|
||||
}
|
||||
};
|
||||
return new YamlCompletionEngine(structureProvider, contextProvider);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2016 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.application.yaml.completions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.springframework.boot.configurationmetadata.Deprecation;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.hover.AbstractPropertyRenderableProvider;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.Type;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil.BeanPropertyNameMode;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypeUtil.EnumCaseMode;
|
||||
import org.springframework.ide.vscode.application.properties.metadata.types.TypedProperty;
|
||||
import org.springframework.ide.vscode.commons.java.IField;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaElement;
|
||||
import org.springframework.ide.vscode.commons.java.IJavaProject;
|
||||
import org.springframework.ide.vscode.commons.java.IMember;
|
||||
import org.springframework.ide.vscode.commons.javadoc.IJavadoc;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
|
||||
/**
|
||||
* Example used as reference for explaingin the meaning of the instance variables:
|
||||
*
|
||||
* foo.bar[0].children.wavelen
|
||||
*/
|
||||
public class JavaTypeNavigationHoverInfo extends AbstractPropertyRenderableProvider {
|
||||
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(JavaTypeNavigationHoverInfo.class.getName());
|
||||
|
||||
/**
|
||||
* Property expression that represents the full path to the point being hovered over.
|
||||
* E.g. foo.bar[0].data.wavelen"
|
||||
*/
|
||||
private final String id;
|
||||
|
||||
/**
|
||||
* Last sgment of the path as a property name.
|
||||
* This is only set if the naviation is accessing a property name (so, for example, will be null for navigation into
|
||||
* indexed element in a sequence/list)
|
||||
* <p>
|
||||
* Example: "wavelen"
|
||||
*/
|
||||
private final String propName;
|
||||
|
||||
/**
|
||||
* The type from which we are navigating.
|
||||
* E.g. the type of "foo.bar[0].data"
|
||||
*/
|
||||
private Type parentType;
|
||||
|
||||
/**
|
||||
* The type at which we arrive.
|
||||
* E.g the type of "foo.bar[0].data.wavelen"
|
||||
*/
|
||||
private Type type;
|
||||
|
||||
private TypeUtil typeUtil;
|
||||
|
||||
private Deprecation deprecation;
|
||||
|
||||
public JavaTypeNavigationHoverInfo(String id, String propName, Type fromType, Type toType, TypeUtil typeUtil) {
|
||||
this.id = id;
|
||||
this.propName = propName;
|
||||
this.parentType = fromType;
|
||||
this.type = toType;
|
||||
this.typeUtil = typeUtil;
|
||||
//Note: If you are considerind caching the result of this method... don't.
|
||||
//The rendered html itself is cached by the superclass, which means this method only gets called once.
|
||||
Map<String, TypedProperty> props = typeUtil.getPropertiesMap(parentType, EnumCaseMode.ALIASED, BeanPropertyNameMode.ALIASED);
|
||||
if (props!=null) {
|
||||
TypedProperty prop = props.get(propName);
|
||||
if (prop!=null) {
|
||||
this.deprecation = prop.getDeprecation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// protected String renderAsHtml() {
|
||||
// JavaTypeLinks jtLinks = new JavaTypeLinks(this);
|
||||
// HtmlBuffer html = new HtmlBuffer();
|
||||
//
|
||||
// html.raw("<b>");
|
||||
// html.text(id);
|
||||
// html.raw("</b>");
|
||||
// html.raw("<br>");
|
||||
//
|
||||
// if (type!=null) {
|
||||
// jtLinks.javaTypeLink(html, typeUtil, type);
|
||||
// } else {
|
||||
// jtLinks.javaTypeLink(html, typeUtil.getJavaProject(), Object.class.toString());
|
||||
// }
|
||||
//
|
||||
// if (isDeprecated()) {
|
||||
// html.raw("<br><br>");
|
||||
// html.bold("Deprecated!");
|
||||
// }
|
||||
//
|
||||
// // String deflt = formatDefaultValue(data.getDefaultValue());
|
||||
// // if (deflt!=null) {
|
||||
// // html.raw("<br><br>");
|
||||
// // html.text("Default: ");
|
||||
// // html.raw("<i>");
|
||||
// // html.text(deflt);
|
||||
// // html.raw("</i>");
|
||||
// // }
|
||||
//
|
||||
// String description = getDescription();
|
||||
// if (description!=null) {
|
||||
// html.raw("<br><br>");
|
||||
// html.raw(description);
|
||||
// }
|
||||
//
|
||||
// return html.toString();
|
||||
// }
|
||||
|
||||
@Override
|
||||
protected boolean isDeprecated() {
|
||||
return deprecation!=null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Renderable getDescription() {
|
||||
try {
|
||||
List<IJavaElement> jes = getAllJavaElements();
|
||||
if (jes!=null) {
|
||||
for (IJavaElement je : jes) {
|
||||
if (je instanceof IMember) {
|
||||
IJavadoc javadoc = je.getJavaDoc();
|
||||
if (javadoc != null) {
|
||||
return javadoc.getRenderable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.log(Level.SEVERE, e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<IJavaElement> getJavaElements() {
|
||||
if (propName!=null) {
|
||||
if (TypeUtil.isMap(parentType)) {
|
||||
Type enumType = typeUtil.getKeyType(parentType);
|
||||
if (typeUtil.isEnum(enumType)) {
|
||||
IField f = typeUtil.getEnumConstant(enumType, propName);
|
||||
if (f!=null) {
|
||||
return ImmutableList.of(f);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
IJavaElement je;
|
||||
Type beanType = parentType;
|
||||
je = typeUtil.getSetter(beanType, propName).get();
|
||||
if (je!=null) {
|
||||
return Collections.singletonList(je);
|
||||
}
|
||||
je = typeUtil.getGetter(beanType, propName);
|
||||
if (je!=null) {
|
||||
return Collections.singletonList(je);
|
||||
}
|
||||
je = typeUtil.getField(beanType, propName);
|
||||
if (je!=null) {
|
||||
return Collections.singletonList(je);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private List<IJavaElement> getAllJavaElements() {
|
||||
if (propName!=null) {
|
||||
Type beanType = parentType;
|
||||
if (TypeUtil.isMap(beanType)) {
|
||||
Type keyType = typeUtil.getKeyType(beanType);
|
||||
if (keyType!=null && typeUtil.isEnum(keyType)) {
|
||||
IField field = typeUtil.getEnumConstant(keyType, propName);
|
||||
if (field!=null) {
|
||||
return ImmutableList.of(field);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ArrayList<IJavaElement> elements = new ArrayList<IJavaElement>(3);
|
||||
maybeAdd(elements, typeUtil.getField(beanType, propName));
|
||||
maybeAdd(elements, typeUtil.getSetter(beanType, propName).get());
|
||||
maybeAdd(elements, typeUtil.getGetter(beanType, propName));
|
||||
if (!elements.isEmpty()) {
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
private void maybeAdd(ArrayList<IJavaElement> elements, IJavaElement e) {
|
||||
if (e!=null) {
|
||||
elements.add(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getDefaultValue() {
|
||||
//Not supported
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IJavaProject getJavaProject() {
|
||||
return typeUtil.getJavaProject();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getType() {
|
||||
return typeUtil.niceTypeName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDeprecationReason() {
|
||||
if (deprecation!=null) {
|
||||
return deprecation.getReason();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDeprecationReplacement() {
|
||||
if (deprecation!=null) {
|
||||
return deprecation.getReplacement();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
|
||||
///////////////////// ported tests from old STS code base ////////////////////////////////////////////////
|
||||
|
||||
@Ignore @Test public void testHovers() throws Exception {
|
||||
@Test public void testHovers() throws Exception {
|
||||
defaultTestData();
|
||||
Editor editor = newEditor(
|
||||
"spring:\n" +
|
||||
@@ -79,16 +79,12 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
" port: 8888"
|
||||
);
|
||||
|
||||
editor.assertIsHoverRegion("spring");
|
||||
editor.assertIsHoverRegion("application");
|
||||
editor.assertIsHoverRegion("name");
|
||||
|
||||
editor.assertIsHoverRegion("server");
|
||||
editor.assertIsHoverRegion("port");
|
||||
|
||||
editor.assertHoverContains("name", "<b>spring.application.name</b>");
|
||||
editor.assertHoverContains("port", "<b>server.port</b>");
|
||||
editor.assertHoverContains("8888", "<b>server.port</b>"); // hover over value show info about corresponding key. Is this logical?
|
||||
editor.assertHoverContains("name", "**spring.application.name**");
|
||||
editor.assertHoverContains("port", "**server.port**");
|
||||
editor.assertHoverContains("8888", "**server.port**"); // hover over value show info about corresponding key. Is this logical?
|
||||
|
||||
editor.assertNoHover("beyond");
|
||||
editor.assertNoHover("the-valid");
|
||||
@@ -110,7 +106,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
editor.assertNoHover("error");
|
||||
}
|
||||
|
||||
@Ignore @Test public void testHoverInfoForEnumValueInMapKey() throws Exception {
|
||||
@Test public void testHoverInfoForEnumValueInMapKey() throws Exception {
|
||||
Editor editor;
|
||||
IJavaProject project = createPredefinedMavenProject("empty-boot-1.3.0-app");
|
||||
useProject(project);
|
||||
@@ -183,7 +179,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Ignore @Test public void testHoverInfoForValueHint() throws Exception {
|
||||
@Test public void testHoverInfoForValueHint() throws Exception {
|
||||
data("my.bonus", "java.lang.String", null, "Bonus type")
|
||||
.valueHint("small", "A small bonus. For a little extra incentive.")
|
||||
.valueHint("large", "An large bonus. For the ones who deserve it.")
|
||||
@@ -217,6 +213,8 @@ 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
|
||||
editor.assertHoverContains("next", "Get the next"); // javadoc from getter
|
||||
|
||||
Reference in New Issue
Block a user