Goto defintion for releases
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.bosh;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.eclipse.lsp4j.Location;
|
||||
import org.eclipse.lsp4j.TextDocumentPositionParams;
|
||||
import org.springframework.ide.vscode.commons.languageserver.definition.SimpleDefinitionFinder;
|
||||
import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlAstCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.ASTTypeCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.yaml.snakeyaml.nodes.Node;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class BoshDefintionFinder extends SimpleDefinitionFinder<BoshLanguageServer> {
|
||||
|
||||
//TODO: lots of common code between BoshDefintionFinder and ConcourseDefinitionFinder.
|
||||
// should be possible to pull up into a common super class.
|
||||
|
||||
private final YamlAstCache asts;
|
||||
private final ASTTypeCache astTypes;
|
||||
private final BoshDeploymentManifestSchema schema;
|
||||
|
||||
private Map<YType, Handler> handlers = new HashMap<>();
|
||||
|
||||
@FunctionalInterface
|
||||
private interface Handler {
|
||||
Flux<Location> handle(Node refNode, TextDocument doc, YamlFileAST ast);
|
||||
}
|
||||
|
||||
public BoshDefintionFinder(BoshLanguageServer server, BoshDeploymentManifestSchema schema, YamlAstCache asts, ASTTypeCache astTypes) {
|
||||
super(server);
|
||||
this.schema = schema;
|
||||
this.asts = asts;
|
||||
this.astTypes = astTypes;
|
||||
for (Pair<YType, YType> defAndRef : schema.getDefAndRefTypes()) {
|
||||
YType def = defAndRef.getLeft();
|
||||
if (def!=null) {
|
||||
YType ref = defAndRef.getRight();
|
||||
if (ref!=null) {
|
||||
findByType(def, ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Flux<Location> findDefinitions(TextDocumentPositionParams params) {
|
||||
try {
|
||||
TextDocument doc = server.getTextDocumentService().get(params);
|
||||
if (doc!=null) {
|
||||
YamlFileAST ast = asts.getSafeAst(doc, false);
|
||||
if (ast!=null) {
|
||||
Node refNode = ast.findNode(doc.toOffset(params.getPosition()));
|
||||
if (refNode!=null) {
|
||||
YType type = astTypes.getType(ast, refNode);
|
||||
if (type!=null) {
|
||||
Handler handler = handlers.get(type);
|
||||
if (handler!=null) {
|
||||
return handler.handle(refNode, doc, ast);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.log(e);
|
||||
}
|
||||
return Flux.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a handler that finds the definitions for a target node within the same document
|
||||
* by retrieving nodes of a given type as candidates.
|
||||
*/
|
||||
protected void findByType(YType def, YType ref) {
|
||||
astTypes.addInterestingType(def);
|
||||
astTypes.addInterestingType(ref);
|
||||
Handler handler = (Node refNode, TextDocument doc, YamlFileAST ast) -> {
|
||||
String uri = doc.getUri();
|
||||
if (uri!=null) {
|
||||
String name = NodeUtil.asScalar(refNode);
|
||||
if (name!=null) {
|
||||
Collection<Node> candidates = astTypes.getNodes(uri, def);
|
||||
return Flux.fromIterable(candidates)
|
||||
.filter((node) -> name.equals(NodeUtil.asScalar(node)))
|
||||
.map((node) -> toLocation(doc, node))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get);
|
||||
}
|
||||
}
|
||||
return Flux.empty();
|
||||
};
|
||||
handlers.put(ref, handler);
|
||||
}
|
||||
|
||||
protected Optional<Location> toLocation(TextDocument doc, Node node) {
|
||||
int start = node.getStartMark().getIndex();
|
||||
int end = node.getEndMark().getIndex();
|
||||
try {
|
||||
return Optional.of(new Location(doc.getUri(), doc.toRange(start, end-start)));
|
||||
} catch (BadLocationException e) {
|
||||
Log.log(e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,13 +11,16 @@
|
||||
package org.springframework.ide.vscode.bosh;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.ide.vscode.bosh.models.CachingModelProvider;
|
||||
import org.springframework.ide.vscode.bosh.models.CloudConfigModel;
|
||||
import org.springframework.ide.vscode.bosh.models.DynamicModelProvider;
|
||||
import org.springframework.ide.vscode.commons.util.Assert;
|
||||
import org.springframework.ide.vscode.commons.util.CollectorUtil;
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParsers;
|
||||
@@ -81,6 +84,7 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
private YType t_var_name_def;
|
||||
private final ASTTypeCache astTypes;
|
||||
private DynamicModelProvider<CloudConfigModel> cloudConfigProvider;
|
||||
private List<Pair<YType, YType>> defAndRefTypes;
|
||||
|
||||
public BoshDeploymentManifestSchema(ASTTypeCache astTypes, DynamicModelProvider<CloudConfigModel> cloudConfigProvider) {
|
||||
this.astTypes = astTypes;
|
||||
@@ -280,14 +284,28 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
|
||||
public Collection<YType> getDefinitionTypes() {
|
||||
if (definitionTypes==null) {
|
||||
definitionTypes = ImmutableList.of(
|
||||
t_instance_group_name_def,
|
||||
t_stemcell_alias_def,
|
||||
t_release_name_def,
|
||||
t_var_name_def
|
||||
);
|
||||
definitionTypes = getDefAndRefTypes().stream()
|
||||
.map(pair -> pair.getLeft())
|
||||
.collect(CollectorUtil.toImmutableList());
|
||||
}
|
||||
return definitionTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Pairs of types. Each pair contains a 'def' type and a 'ref' type. Nodes with the ref-type
|
||||
* shall be interpreted as reference to a corresponding node with the 'def' type if the def and ref node
|
||||
* contain the same scalar value.
|
||||
*/
|
||||
public Collection<Pair<YType, YType>> getDefAndRefTypes() {
|
||||
if (defAndRefTypes==null) {
|
||||
defAndRefTypes = ImmutableList.of(
|
||||
Pair.of(t_instance_group_name_def, null),
|
||||
Pair.of(t_stemcell_alias_def, null),
|
||||
Pair.of(t_release_name_def, t_release_name_ref),
|
||||
Pair.of(t_var_name_def, null)
|
||||
);
|
||||
}
|
||||
return defAndRefTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocu
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.util.text.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.ast.YamlAstCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.SchemaBasedYamlAssistContextProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.YamlAssistContextProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.YamlCompletionEngine;
|
||||
@@ -34,18 +34,18 @@ import org.springframework.ide.vscode.commons.yaml.reconcile.ASTTypeCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.TypeBasedYamlSymbolHandler;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaBasedReconcileEngine;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureProvider;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
public class BoshLanguageServer extends SimpleLanguageServer {
|
||||
|
||||
private Yaml yaml = new Yaml();
|
||||
private final LazyCompletionResolver completionResolver = new LazyCompletionResolver(); //Set to null to disable lazy resolving
|
||||
private final VscodeCompletionEngineAdapter completionEngine;
|
||||
|
||||
public BoshLanguageServer(DynamicModelProvider<CloudConfigModel> cloudConfigProvider) {
|
||||
super("vscode-bosh");
|
||||
YamlASTProvider parser = new YamlParser(yaml);
|
||||
YamlAstCache asts = new YamlAstCache();
|
||||
YamlASTProvider parser = asts.getAstProvider(false);
|
||||
SimpleTextDocumentService documents = getTextDocumentService();
|
||||
|
||||
ASTTypeCache astTypeCache = new ASTTypeCache();
|
||||
BoshDeploymentManifestSchema schema = new BoshDeploymentManifestSchema(astTypeCache, cloudConfigProvider);
|
||||
|
||||
@@ -67,6 +67,7 @@ public class BoshLanguageServer extends SimpleLanguageServer {
|
||||
documents.onCompletion(completionEngine::getCompletions);
|
||||
documents.onCompletionResolve(completionEngine::resolveCompletion);
|
||||
documents.onHover(hoverEngine ::getHover);
|
||||
documents.onDefinition(new BoshDefintionFinder(this, schema, asts, astTypeCache));
|
||||
}
|
||||
|
||||
private void validateOnDocumentChange(IReconcileEngine engine, TextDocument doc) {
|
||||
|
||||
@@ -26,7 +26,6 @@ import org.springframework.ide.vscode.commons.yaml.reconcile.YamlSchemaProblems;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.Editor;
|
||||
import org.springframework.ide.vscode.languageserver.testharness.LanguageServerHarness;
|
||||
|
||||
|
||||
public class BoshEditorTest {
|
||||
|
||||
LanguageServerHarness harness;
|
||||
@@ -920,4 +919,34 @@ public class BoshEditorTest {
|
||||
assertContains("Reading cloud config timed out", completion.getDocumentation());
|
||||
}
|
||||
|
||||
@Test public void gotoReleaseDefinition() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"name: foo\n" +
|
||||
"instance_groups: \n" +
|
||||
"- name: some-server\n" +
|
||||
" jobs:\n" +
|
||||
" - release: some-release\n" +
|
||||
"- name: some-other-server\n" +
|
||||
" jobs:\n" +
|
||||
" - release: bogus-release\n" +
|
||||
"releases:\n" +
|
||||
"- name: some-release\n" +
|
||||
" url: https://release-hub.info/some-release.tar.gz?version=99.3.2\n" +
|
||||
" sha1: asddsfsd\n" +
|
||||
"- name: other-release\n" +
|
||||
" url: https://release-hub.info/other-release.tar.gz?version=99.3.2\n" +
|
||||
" sha1: asddsfsd\n"
|
||||
);
|
||||
|
||||
editor.assertGotoDefinition(editor.positionOf("some-release"),
|
||||
editor.rangeOf(
|
||||
"releases:\n" +
|
||||
"- name: some-release\n"
|
||||
,
|
||||
"some-release"
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BinaryOperator;
|
||||
@@ -19,6 +21,7 @@ import java.util.stream.Collector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.HashMultiset;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMultiset;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
@@ -64,4 +67,36 @@ public class CollectorUtil {
|
||||
};
|
||||
}
|
||||
|
||||
public static <T> Collector<T, ArrayList<T>, ImmutableList<T>> toImmutableList() {
|
||||
return new Collector<T, ArrayList<T>, ImmutableList<T>>() {
|
||||
|
||||
@Override
|
||||
public Supplier<ArrayList<T>> supplier() {
|
||||
return ArrayList::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiConsumer<ArrayList<T>, T> accumulator() {
|
||||
return (a, e) -> a.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinaryOperator<ArrayList<T>> combiner() {
|
||||
return (a1, a2) -> {
|
||||
a1.addAll(a2);
|
||||
return a1;
|
||||
};
|
||||
}
|
||||
@Override
|
||||
public Function<ArrayList<T>, ImmutableList<T>> finisher() {
|
||||
return ImmutableList::copyOf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Collector.Characteristics> characteristics() {
|
||||
return ImmutableSet.of(Collector.Characteristics.UNORDERED);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.yaml.ast;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.StaleFallbackCache;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
public class YamlAstCache {
|
||||
|
||||
private final StaleFallbackCache<String, YamlFileAST> asts = new StaleFallbackCache<>();
|
||||
private final YamlParser parser;
|
||||
|
||||
public YamlAstCache() {
|
||||
Yaml yaml = new Yaml();
|
||||
this.parser = new YamlParser(yaml);
|
||||
}
|
||||
|
||||
public YamlASTProvider getAstProvider(boolean allowStaleAsts) {
|
||||
return (IDocument doc) -> {
|
||||
String uri = doc.getUri();
|
||||
if (uri!=null) {
|
||||
return asts.get(uri, doc.getVersion(), allowStaleAsts, () -> {
|
||||
return parser.getAST(doc);
|
||||
});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
public YamlFileAST getSafeAst(IDocument doc) {
|
||||
return getSafeAst(doc, true);
|
||||
}
|
||||
|
||||
public YamlFileAST getAst(IDocument doc, boolean allowStaleAst) throws Exception {
|
||||
return getAstProvider(allowStaleAst).getAST(doc);
|
||||
}
|
||||
|
||||
public YamlFileAST getSafeAst(IDocument doc, boolean allowStaleAst) {
|
||||
if (doc!=null) {
|
||||
try {
|
||||
return getAst(doc, allowStaleAst);
|
||||
} catch (Exception e) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -164,5 +164,15 @@ public class ASTTypeCache implements ITypeCollector {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Collection<Node> getNodes(String uri, YType type) {
|
||||
NodeTypes nodeMap = getNodeTypes(uri);
|
||||
if (nodeMap!=null) {
|
||||
Collection<Node> nodes = nodeMap.getNodes(type);
|
||||
if (nodes!=null) {
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.concourse.util;
|
||||
package org.springframework.ide.vscode.commons.yaml.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -712,7 +712,7 @@ public class Editor {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the position of (the middle of) a snippet of text in the document.
|
||||
* Determines the position of a snippet of text in the document.
|
||||
*
|
||||
* @param contextSnippet A larger snippet containing the actual snippet to look for.
|
||||
* This larger snippet is used to narrow the section of the document
|
||||
@@ -725,6 +725,10 @@ public class Editor {
|
||||
return r==null?null:r.getStart();
|
||||
}
|
||||
|
||||
public Position positionOf(String snippet) throws Exception {
|
||||
return positionOf(snippet, snippet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the range of a snippet of text in the document.
|
||||
*
|
||||
@@ -795,4 +799,5 @@ public class Editor {
|
||||
this.selectionStart = this.selectionEnd = doc.toOffset(position);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.ide.vscode.commons.util.BadLocationException;
|
||||
import org.springframework.ide.vscode.commons.util.Log;
|
||||
import org.springframework.ide.vscode.commons.util.text.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlAstCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.reconcile.ASTTypeCache;
|
||||
@@ -36,14 +37,14 @@ public class ConcourseDefinitionFinder extends SimpleDefinitionFinder<ConcourseL
|
||||
Flux<Location> handle(Node refNode, TextDocument doc, YamlFileAST ast);
|
||||
}
|
||||
|
||||
private final ConcourseModel models;
|
||||
private ASTTypeCache astTypes;
|
||||
private final ASTTypeCache astTypes;
|
||||
private Map<YType, Handler> handlers = new HashMap<>();
|
||||
private final YamlAstCache asts;
|
||||
|
||||
public ConcourseDefinitionFinder(ConcourseLanguageServer server, ConcourseModel models, PipelineYmlSchema schema) {
|
||||
super(server);
|
||||
this.models = models;
|
||||
this.astTypes = models.getAstTypeCache();
|
||||
this.asts = models.getAstCache();
|
||||
findByPath(schema.t_resource_name, ConcourseModel.RESOURCE_NAMES_PATH);
|
||||
findByPath(schema.t_maybe_resource_name, ConcourseModel.RESOURCE_NAMES_PATH);
|
||||
findByPath(schema.t_job_name, ConcourseModel.JOB_NAMES_PATH);
|
||||
@@ -58,7 +59,7 @@ public class ConcourseDefinitionFinder extends SimpleDefinitionFinder<ConcourseL
|
||||
* @param definitionsPath Path that points to all nodes within the same file corresponding
|
||||
* to definitions of nodes of the given type.
|
||||
*/
|
||||
private void findByPath(YType refType, YamlPath definitionsPath) {
|
||||
protected void findByPath(YType refType, YamlPath definitionsPath) {
|
||||
astTypes.addInterestingType(refType);
|
||||
Handler handler = (Node refNode, TextDocument doc, YamlFileAST ast) -> {
|
||||
String name = NodeUtil.asScalar(refNode);
|
||||
@@ -79,7 +80,7 @@ public class ConcourseDefinitionFinder extends SimpleDefinitionFinder<ConcourseL
|
||||
try {
|
||||
TextDocument doc = server.getTextDocumentService().get(params);
|
||||
if (doc!=null) {
|
||||
YamlFileAST ast = models.getSafeAst(doc, false);
|
||||
YamlFileAST ast = asts.getSafeAst(doc, false);
|
||||
if (ast!=null) {
|
||||
Node refNode = ast.findNode(doc.toOffset(params.getPosition()));
|
||||
if (refNode!=null) {
|
||||
|
||||
@@ -49,7 +49,7 @@ public class ConcourseLanguageServer extends SimpleLanguageServer {
|
||||
YamlStructureProvider structureProvider = YamlStructureProvider.DEFAULT;
|
||||
SimpleTextDocumentService documents = getTextDocumentService();
|
||||
ConcourseModel models = new ConcourseModel(this);
|
||||
YamlASTProvider currentAsts = models.getAstProvider(false);
|
||||
YamlASTProvider currentAsts = models.getAstCache().getAstProvider(false);
|
||||
private SchemaSpecificPieces forPipelines;
|
||||
private SchemaSpecificPieces forTasks;
|
||||
private final YamlQuickfixes yamlQuickfixes;
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.text.IDocument;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlASTProvider;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlAstCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlParser;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.ASTRootCursor;
|
||||
@@ -52,8 +53,8 @@ import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory.YBeanUnio
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraint;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YValueHint;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.StaleFallbackCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.util.Streams;
|
||||
import org.springframework.ide.vscode.concourse.util.StaleFallbackCache;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.error.YAMLException;
|
||||
import org.yaml.snakeyaml.nodes.MappingNode;
|
||||
@@ -112,7 +113,7 @@ public class ConcourseModel {
|
||||
if (job!=null) {
|
||||
//Only check if the job exists. Otherwise the extra checks will show 'redundant' errors (e.g.
|
||||
// complaining that 'some-job' doesn't ineract with a resource (because the resource doesn't exist).
|
||||
YamlFileAST root = this.getSafeAst(dc.getDocument());
|
||||
YamlFileAST root = asts.getSafeAst(dc.getDocument());
|
||||
if (root!=null) {
|
||||
Node stepNode = path.dropLast().traverseToNode(root);
|
||||
if (stepNode!=null) {
|
||||
@@ -256,9 +257,7 @@ public class ConcourseModel {
|
||||
valueAt("name")
|
||||
);
|
||||
|
||||
private final YamlParser parser;
|
||||
private final StaleFallbackCache<String, YamlFileAST> asts = new StaleFallbackCache<>();
|
||||
|
||||
private final YamlAstCache asts = new YamlAstCache();
|
||||
private final ASTTypeCache astTypes = new ASTTypeCache();
|
||||
|
||||
private ResourceTypeRegistry resourceTypes;
|
||||
@@ -268,8 +267,6 @@ public class ConcourseModel {
|
||||
private YBeanUnionType stepType;
|
||||
|
||||
public ConcourseModel(SimpleLanguageServer languageServer) {
|
||||
Yaml yaml = new Yaml();
|
||||
this.parser = new YamlParser(yaml);
|
||||
this.snippetBuilderFactory = languageServer::createSnippetBuilder;
|
||||
}
|
||||
|
||||
@@ -368,7 +365,7 @@ public class ConcourseModel {
|
||||
public Node getParentPropertyNode(String propName, DynamicSchemaContext dc) {
|
||||
YamlPath path = dc.getPath();
|
||||
if (path!=null) {
|
||||
YamlFileAST root = this.getSafeAst(dc.getDocument());
|
||||
YamlFileAST root = asts.getSafeAst(dc.getDocument());
|
||||
if (root!=null) {
|
||||
return path.dropLast().append(YamlPathSegment.valueAt(propName)).traverseToNode(root);
|
||||
}
|
||||
@@ -402,7 +399,7 @@ public class ConcourseModel {
|
||||
if (doc!=null) {
|
||||
String uri = doc.getUri();
|
||||
if (uri!=null) {
|
||||
YamlFileAST ast = getAst(doc, true);
|
||||
YamlFileAST ast = asts.getAst(doc, true);
|
||||
return astFunction.apply(ast);
|
||||
}
|
||||
}
|
||||
@@ -414,36 +411,6 @@ public class ConcourseModel {
|
||||
return null;
|
||||
}
|
||||
|
||||
public YamlFileAST getSafeAst(IDocument doc) {
|
||||
return getSafeAst(doc, true);
|
||||
}
|
||||
|
||||
public YamlFileAST getAst(IDocument doc, boolean allowStaleAst) throws Exception {
|
||||
return getAstProvider(allowStaleAst).getAST(doc);
|
||||
}
|
||||
|
||||
public YamlASTProvider getAstProvider(boolean allowStaleAsts) {
|
||||
return (IDocument doc) -> {
|
||||
String uri = doc.getUri();
|
||||
if (uri!=null) {
|
||||
return asts.get(uri, doc.getVersion(), allowStaleAsts, () -> {
|
||||
return parser.getAST(doc);
|
||||
});
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
public YamlFileAST getSafeAst(IDocument doc, boolean allowStaleAst) {
|
||||
if (doc!=null) {
|
||||
try {
|
||||
return getAst(doc, allowStaleAst);
|
||||
} catch (Exception e) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ASTTypeCache getAstTypeCache() {
|
||||
return astTypes;
|
||||
@@ -458,4 +425,8 @@ public class ConcourseModel {
|
||||
this.stepType = step;
|
||||
}
|
||||
|
||||
public YamlAstCache getAstCache() {
|
||||
return this.asts;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParsers;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.NodeUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlAstCache;
|
||||
import org.springframework.ide.vscode.commons.yaml.ast.YamlFileAST;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
|
||||
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
|
||||
@@ -134,6 +135,7 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
private final ResourceTypeRegistry resourceTypes = new ResourceTypeRegistry();
|
||||
|
||||
private final ConcourseModel models;
|
||||
private final YamlAstCache asts;
|
||||
|
||||
public final YType t_semver = f.yatomic("Semver")
|
||||
.parseWith(ValueParsers.NE_STRING); //TODO: use real semver parser.
|
||||
@@ -155,9 +157,9 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
|
||||
private List<YType> definitionTypes = new ArrayList<>();
|
||||
|
||||
|
||||
public PipelineYmlSchema(ConcourseModel models) {
|
||||
this.models = models;
|
||||
this.asts = models.getAstCache();
|
||||
models.setResourceTypeRegistry(resourceTypes);
|
||||
TYPE_UTIL = f.TYPE_UTIL;
|
||||
|
||||
@@ -659,7 +661,7 @@ public class PipelineYmlSchema implements YamlSchema {
|
||||
private String getSiblingPropertyValue(DynamicSchemaContext dc, String propName) {
|
||||
YamlPath path = dc.getPath();
|
||||
if (path!=null) {
|
||||
YamlFileAST root = models.getSafeAst(dc.getDocument());
|
||||
YamlFileAST root = asts.getSafeAst(dc.getDocument());
|
||||
if (root!=null) {
|
||||
return NodeUtil.asScalar(path.append(YamlPathSegment.valueAt(propName)).traverseToNode(root));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user