diff --git a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/AbstractPropertyRenderableProvider.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/hover/AbstractPropertyRenderableProvider.java similarity index 85% rename from vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/AbstractPropertyRenderableProvider.java rename to vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/hover/AbstractPropertyRenderableProvider.java index bbf5e74c3..7ac1ed12a 100644 --- a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/AbstractPropertyRenderableProvider.java +++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/hover/AbstractPropertyRenderableProvider.java @@ -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 diff --git a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/PropertyRenderableProvider.java b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/hover/PropertyRenderableProvider.java similarity index 90% rename from vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/PropertyRenderableProvider.java rename to vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/hover/PropertyRenderableProvider.java index 5e7bd2e7d..3bd66282f 100644 --- a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/PropertyRenderableProvider.java +++ b/vscode-extensions/commons/application-properties-metadata/src/main/java/org/springframework/ide/vscode/application/properties/metadata/hover/PropertyRenderableProvider.java @@ -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; diff --git a/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Log.java b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Log.java index cbd54166f..fcb29aaee 100644 --- a/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Log.java +++ b/vscode-extensions/commons/commons-util/src/main/java/org/springframework/ide/vscode/commons/util/Log.java @@ -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 { diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/AbstractYamlAssistContext.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/AbstractYamlAssistContext.java index a24a03bd1..269494ddc 100644 --- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/AbstractYamlAssistContext.java +++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/AbstractYamlAssistContext.java @@ -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(); + } } diff --git a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/PropertiesHoverCalculator.java b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/PropertiesHoverCalculator.java index 6486cf78d..a147ed4e8 100644 --- a/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/PropertiesHoverCalculator.java +++ b/vscode-extensions/vscode-application-properties/src/main/java/org/springframework/ide/vscode/application/properties/hover/PropertiesHoverCalculator.java @@ -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; diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/ApplicationYamlLanguageServer.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/ApplicationYamlLanguageServer.java index e2d398328..928533b54 100644 --- a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/ApplicationYamlLanguageServer.java +++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/ApplicationYamlLanguageServer.java @@ -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 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) { diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/ApplicationYamlAssistContext.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/ApplicationYamlAssistContext.java index 3d03e724e..4418665ff 100644 --- a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/ApplicationYamlAssistContext.java +++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/ApplicationYamlAssistContext.java @@ -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 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 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 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 index, final PropertyCompletionFactory completionFactory, final TypeUtil typeUtil, final RelaxedNameConfig conf) { return new TopLevelAssistContext() { diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/ApplicationYamlCompletionEngine.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/ApplicationYamlCompletionEngine.java deleted file mode 100644 index 3d351aac9..000000000 --- a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/ApplicationYamlCompletionEngine.java +++ /dev/null @@ -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 index = indexProvider.getIndex(doc); - return ApplicationYamlAssistContext.global(index, completionFactory, typeUtilProvider.getTypeUtil(doc), conf); - } - }; - return new YamlCompletionEngine(structureProvider, contextProvider); - } -} diff --git a/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/JavaTypeNavigationHoverInfo.java b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/JavaTypeNavigationHoverInfo.java new file mode 100644 index 000000000..732c3c993 --- /dev/null +++ b/vscode-extensions/vscode-application-yaml/src/main/java/org/springframework/ide/vscode/application/yaml/completions/JavaTypeNavigationHoverInfo.java @@ -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) + *

+ * 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 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(""); +// html.text(id); +// html.raw(""); +// html.raw("
"); +// +// if (type!=null) { +// jtLinks.javaTypeLink(html, typeUtil, type); +// } else { +// jtLinks.javaTypeLink(html, typeUtil.getJavaProject(), Object.class.toString()); +// } +// +// if (isDeprecated()) { +// html.raw("

"); +// html.bold("Deprecated!"); +// } +// +// // String deflt = formatDefaultValue(data.getDefaultValue()); +// // if (deflt!=null) { +// // html.raw("

"); +// // html.text("Default: "); +// // html.raw(""); +// // html.text(deflt); +// // html.raw(""); +// // } +// +// String description = getDescription(); +// if (description!=null) { +// html.raw("

"); +// html.raw(description); +// } +// +// return html.toString(); +// } + + @Override + protected boolean isDeprecated() { + return deprecation!=null; + } + + @Override + protected Renderable getDescription() { + try { + List 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 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 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 elements = new ArrayList(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 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; + } +} \ No newline at end of file diff --git a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/application/yaml/ApplicationYamlEditorTest.java b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/application/yaml/ApplicationYamlEditorTest.java index 3fcc4048c..93f02c82b 100644 --- a/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/application/yaml/ApplicationYamlEditorTest.java +++ b/vscode-extensions/vscode-application-yaml/src/test/java/org/springframework/ide/vscode/application/yaml/ApplicationYamlEditorTest.java @@ -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", "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.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