Search in sources :

Example 6 with YTypedProperty

use of org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty in project sts4 by spring-projects.

the class SchemaBasedSnippetGenerator method generateBeanSnippet.

private void generateBeanSnippet(List<YTypedProperty> props, SnippetBuilder builder, int indent, int nestingLimit) {
    if (nestingLimit > 0 && !props.isEmpty()) {
        boolean first = true;
        for (YTypedProperty p : props) {
            if (!first) {
                builder.newline(indent);
            }
            builder.text(p.getName());
            builder.text(":");
            generateNestedSnippet(false, p.getType(), builder, indent, nestingLimit - 1);
            first = false;
        }
    } else {
        // reached the limit of bean number of nested property expansions allowed.
        builder.placeHolder();
    }
}
Also used : YTypedProperty(org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty)

Example 7 with YTypedProperty

use of org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty in project sts4 by spring-projects.

the class YTypeAssistContext method getKeyCompletions.

public List<ICompletionProposal> getKeyCompletions(YamlDocument doc, SNode node, int offset, String query) throws Exception {
    int queryOffset = offset - query.length();
    DynamicSchemaContext dynamicCtxt = getSchemaContext();
    List<YTypedProperty> allProperties = typeUtil.getProperties(type);
    if (CollectionUtil.hasElements(allProperties)) {
        List<List<YTypedProperty>> tieredProperties = sortIntoTiers(allProperties);
        Set<String> definedProps = dynamicCtxt.getDefinedProperties();
        List<ICompletionProposal> proposals = new ArrayList<>();
        boolean suggestDeprecated = typeUtil.suggestDeprecatedProperties();
        YamlIndentUtil indenter = new YamlIndentUtil(doc);
        for (List<YTypedProperty> thisTier : tieredProperties) {
            List<YTypedProperty> undefinedProps = thisTier.stream().filter(p -> !definedProps.contains(p.getName()) && (suggestDeprecated || !p.isDeprecated())).collect(Collectors.toList());
            if (!undefinedProps.isEmpty()) {
                for (YTypedProperty p : undefinedProps) {
                    String name = p.getName();
                    double score = FuzzyMatcher.matchScore(query, name);
                    if (score != 0) {
                        TypeBasedSnippetProvider snippetProvider = typeUtil.getSnippetProvider();
                        DocumentEdits edits;
                        if (snippetProvider != null) {
                            // Generate edits from snippet
                            Snippet snippet = snippetProvider.getSnippet(p);
                            edits = createEditFromSnippet(doc, node, offset, query, indenter, snippet);
                        } else {
                            // Generate edits the old-fashioned way
                            edits = new DocumentEdits(doc.getDocument());
                            YType YType = p.getType();
                            edits.delete(queryOffset, query);
                            int referenceIndent = doc.getColumn(queryOffset);
                            boolean needNewline = node.getNodeType() == SNodeType.KEY;
                            StringBuilder snippet = new StringBuilder();
                            if (needNewline) {
                                snippet.append("\n");
                                referenceIndent = YamlIndentUtil.getNewChildKeyIndent(node);
                            } else if (queryOffset > 0 && !Character.isWhitespace(doc.getChar(queryOffset - 1))) {
                                // See https://www.pivotaltracker.com/story/show/137722057
                                snippet.append(" ");
                                referenceIndent++;
                            }
                            snippet.append(p.getName());
                            snippet.append(":");
                            snippet.append(appendTextFor(YType));
                            edits.insert(queryOffset, indenter.applyIndentation(snippet.toString(), referenceIndent));
                        }
                        ICompletionProposal completion = completionFactory().beanProperty(doc.getDocument(), contextPath.toPropString(), getType(), query, p, score, edits, typeUtil);
                        if (p.isDeprecated() && completion instanceof ScoreableProposal) {
                            completion.deemphasize(DEEMP_DEPRECATION);
                        }
                        proposals.add(completion);
                    }
                }
            }
            // We should only move on to the next tier if all required properties in this tier are defined.
            if (undefinedProps.stream().anyMatch(p -> p.isRequired())) {
                // stop here, take no more from next tier!
                return proposals;
            }
        }
        return proposals;
    }
    return Collections.emptyList();
}
Also used : LoggerFactory(org.slf4j.LoggerFactory) YTypeUtil(org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil) FuzzyMatcher(org.springframework.ide.vscode.commons.util.FuzzyMatcher) YamlIndentUtil(org.springframework.ide.vscode.commons.yaml.util.YamlIndentUtil) ArrayList(java.util.ArrayList) Strings(com.google.common.base.Strings) YamlPathSegmentType(org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment.YamlPathSegmentType) ImmutableList(com.google.common.collect.ImmutableList) DEEMP_DEPRECATION(org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal.DEEMP_DEPRECATION) Map(java.util.Map) ValueParseException(org.springframework.ide.vscode.commons.util.ValueParseException) YamlPath(org.springframework.ide.vscode.commons.yaml.path.YamlPath) DynamicSchemaContext(org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext) SNodeType(org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNodeType) YamlPathSegment(org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment) Logger(org.slf4j.Logger) ExceptionUtil(org.springframework.ide.vscode.commons.util.ExceptionUtil) YTypedProperty(org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty) Log(org.springframework.ide.vscode.commons.util.Log) DocumentRegion(org.springframework.ide.vscode.commons.util.text.DocumentRegion) ISubCompletionEngine(org.springframework.ide.vscode.commons.yaml.schema.ISubCompletionEngine) ScoreableProposal(org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal) Collection(java.util.Collection) TypeBasedSnippetProvider(org.springframework.ide.vscode.commons.yaml.snippet.TypeBasedSnippetProvider) Set(java.util.Set) PartialCollection(org.springframework.ide.vscode.commons.util.PartialCollection) YamlDocument(org.springframework.ide.vscode.commons.yaml.structure.YamlDocument) DEEMP_DASH_PROPOSAL(org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal.DEEMP_DASH_PROPOSAL) Collectors(java.util.stream.Collectors) YType(org.springframework.ide.vscode.commons.yaml.schema.YType) YPropertyInfoTemplates(org.springframework.ide.vscode.commons.yaml.hover.YPropertyInfoTemplates) List(java.util.List) CollectionUtil(org.springframework.ide.vscode.commons.util.CollectionUtil) DocumentEdits(org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits) ICompletionProposal(org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal) SNodeDynamicSchemaContext(org.springframework.ide.vscode.commons.yaml.schema.SNodeDynamicSchemaContext) SNode(org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode) YValueHint(org.springframework.ide.vscode.commons.yaml.schema.YValueHint) Snippet(org.springframework.ide.vscode.commons.yaml.snippet.Snippet) Renderable(org.springframework.ide.vscode.commons.util.Renderable) ValueProposal(org.springframework.ide.vscode.commons.yaml.completion.DefaultCompletionFactory.ValueProposal) Collections(java.util.Collections) DocumentEdits(org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits) ScoreableProposal(org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal) ArrayList(java.util.ArrayList) DynamicSchemaContext(org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext) SNodeDynamicSchemaContext(org.springframework.ide.vscode.commons.yaml.schema.SNodeDynamicSchemaContext) Snippet(org.springframework.ide.vscode.commons.yaml.snippet.Snippet) YValueHint(org.springframework.ide.vscode.commons.yaml.schema.YValueHint) YamlIndentUtil(org.springframework.ide.vscode.commons.yaml.util.YamlIndentUtil) ICompletionProposal(org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal) TypeBasedSnippetProvider(org.springframework.ide.vscode.commons.yaml.snippet.TypeBasedSnippetProvider) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) YTypedProperty(org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty) YType(org.springframework.ide.vscode.commons.yaml.schema.YType)

Example 8 with YTypedProperty

use of org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty in project sts4 by spring-projects.

the class YTypeAssistContext method sortIntoTiers.

/**
 * Divides a given list of properties into tiers of decreasing significance. Property tiering
 * is a mechanism to reduce 'noise' in content assist proposals. Only properties of the
 * first X tiers will be used, until those tiers no longer have undefined required properties.
 * <p>
 * This allows, for example, to only suggest a 'name' property when starting to define
 * a new named entity. This is what a sane user would probably want, even though
 * in theory they would be free to define the properties in any order they want.
 */
protected List<List<YTypedProperty>> sortIntoTiers(List<YTypedProperty> properties) {
    boolean tieredOptionals = typeUtil.tieredOptionalPropertyProposals();
    if (properties.isEmpty()) {
        // Nothing to sort
        return ImmutableList.of();
    } else {
        ImmutableList.Builder<YTypedProperty> primary = ImmutableList.builder();
        ImmutableList.Builder<YTypedProperty> tier2 = ImmutableList.builder();
        ImmutableList.Builder<YTypedProperty> tier3 = ImmutableList.builder();
        for (YTypedProperty p : properties) {
            if (p.isPrimary()) {
                primary.add(p);
            } else if (!tieredOptionals || p.isRequired()) {
                tier2.add(p);
            } else {
                tier3.add(p);
            }
        }
        if (tieredOptionals) {
            return ImmutableList.of(primary.build(), tier2.build(), tier3.build());
        } else {
            return ImmutableList.of(primary.build(), tier2.build());
        }
    }
}
Also used : ImmutableList(com.google.common.collect.ImmutableList) YTypedProperty(org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty)

Example 9 with YTypedProperty

use of org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty in project sts4 by spring-projects.

the class SchemaBasedYamlASTReconciler method reconcile.

private void reconcile(YamlFileAST ast, YamlPath path, Node parent, Node node, YType _type) {
    // IDocument doc = ast.getDocument();
    if (_type != null && !skipReconciling(node)) {
        DynamicSchemaContext schemaContext = new ASTDynamicSchemaContext(ast, path, node);
        YType type = typeUtil.inferMoreSpecificType(_type, schemaContext);
        if (typeCollector != null) {
            typeCollector.accept(node, type);
        }
        checkConstraints(parent, node, type, schemaContext);
        switch(getNodeId(node)) {
            case mapping:
                MappingNode map = (MappingNode) node;
                checkForDuplicateKeys(map);
                if (typeUtil.isMap(type)) {
                    for (NodeTuple entry : map.getValue()) {
                        String key = NodeUtil.asScalar(entry.getKeyNode());
                        reconcile(ast, keyAt(path, key), map, entry.getKeyNode(), typeUtil.getKeyType(type));
                        reconcile(ast, valueAt(path, key), map, entry.getValueNode(), typeUtil.getDomainType(type));
                    }
                } else if (typeUtil.isBean(type)) {
                    Map<String, YTypedProperty> beanProperties = typeUtil.getPropertiesMap(type);
                    checkRequiredProperties(parent, map, type, beanProperties, schemaContext);
                    for (NodeTuple entry : map.getValue()) {
                        Node keyNode = entry.getKeyNode();
                        String key = NodeUtil.asScalar(keyNode);
                        if (key == null) {
                            expectScalar(node);
                        } else {
                            YTypedProperty prop = beanProperties.get(key);
                            if (prop == null) {
                                unknownBeanProperty(keyNode, type, key);
                            } else {
                                if (prop.isDeprecated()) {
                                    String msg = prop.getDeprecationMessage();
                                    if (StringUtil.hasText(msg)) {
                                        problems.accept(YamlSchemaProblems.deprecatedProperty(msg, keyNode));
                                    } else {
                                        problems.accept(YamlSchemaProblems.deprecatedProperty(keyNode, type, prop));
                                    }
                                }
                                reconcile(ast, valueAt(path, key), map, entry.getValueNode(), prop.getType());
                            }
                        }
                    }
                } else {
                    expectTypeButFoundMap(type, node);
                }
                break;
            case sequence:
                SequenceNode seq = (SequenceNode) node;
                if (typeUtil.isSequencable(type)) {
                    for (int i = 0; i < seq.getValue().size(); i++) {
                        Node el = seq.getValue().get(i);
                        reconcile(ast, valueAt(path, i), seq, el, typeUtil.getDomainType(type));
                    }
                } else {
                    expectTypeButFoundSequence(type, node);
                }
                break;
            case scalar:
                if (typeUtil.isAtomic(type)) {
                    SchemaContextAware<ValueParser> parserProvider = typeUtil.getValueParser(type);
                    if (parserProvider != null) {
                        // Take care not to execute parserProvider early just to check how long it should be delayed.
                        delayedConstraints.add(() -> {
                            parserProvider.safeWithContext(schemaContext).ifPresent(parser -> {
                                if (parser.longRunning()) {
                                    slowDelayedConstraints.add(() -> {
                                        parse(ast, node, type, parser);
                                    });
                                } else {
                                    parse(ast, node, type, parser);
                                }
                            });
                        });
                    }
                } else {
                    expectTypeButFoundScalar(type, node);
                }
                break;
            default:
        }
    }
}
Also used : ValueParser(org.springframework.ide.vscode.commons.util.ValueParser) SequenceNode(org.yaml.snakeyaml.nodes.SequenceNode) MappingNode(org.yaml.snakeyaml.nodes.MappingNode) Node(org.yaml.snakeyaml.nodes.Node) ScalarNode(org.yaml.snakeyaml.nodes.ScalarNode) DynamicSchemaContext(org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext) ASTDynamicSchemaContext(org.springframework.ide.vscode.commons.yaml.schema.ASTDynamicSchemaContext) SequenceNode(org.yaml.snakeyaml.nodes.SequenceNode) Constraint(org.springframework.ide.vscode.commons.yaml.schema.constraints.Constraint) MappingNode(org.yaml.snakeyaml.nodes.MappingNode) ASTDynamicSchemaContext(org.springframework.ide.vscode.commons.yaml.schema.ASTDynamicSchemaContext) YType(org.springframework.ide.vscode.commons.yaml.schema.YType) NodeTuple(org.yaml.snakeyaml.nodes.NodeTuple) Map(java.util.Map) YTypedProperty(org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty)

Example 10 with YTypedProperty

use of org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty in project sts4 by spring-projects.

the class SchemaBasedSnippetGenerator method generateFullSnippet.

private Snippet generateFullSnippet(YType type, int indent) {
    if (typeUtil.isBean(type)) {
        SnippetBuilder builder = snippetBuilderFactory.get();
        List<YTypedProperty> requiredProps = typeUtil.getProperties(type).stream().filter(p -> p.isRequired()).collect(CollectorUtil.toImmutableList());
        if (!requiredProps.isEmpty()) {
            generateBeanSnippet(requiredProps, builder, indent, maxNesting);
        }
        if (builder.getPlaceholderCount() >= 2) {
            return new Snippet(typeUtil.niceTypeName(type) + " Snippet", builder.build(), (dc) -> requiredProps.stream().noneMatch(p -> dc.getDefinedProperties().contains(p.getName())));
        }
    }
    return null;
}
Also used : List(java.util.List) YTypedProperty(org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty) CollectorUtil(org.springframework.ide.vscode.commons.util.CollectorUtil) ImmutableList(com.google.common.collect.ImmutableList) Collection(java.util.Collection) PlaceHolderString(org.springframework.ide.vscode.commons.languageserver.util.PlaceHolderString) YTypeUtil(org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil) Supplier(com.google.common.base.Supplier) YamlIndentUtil(org.springframework.ide.vscode.commons.yaml.util.YamlIndentUtil) Collectors(java.util.stream.Collectors) YType(org.springframework.ide.vscode.commons.yaml.schema.YType) SnippetBuilder(org.springframework.ide.vscode.commons.languageserver.util.SnippetBuilder) SnippetBuilder(org.springframework.ide.vscode.commons.languageserver.util.SnippetBuilder) YTypedProperty(org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty)

Aggregations

YTypedProperty (org.springframework.ide.vscode.commons.yaml.schema.YTypedProperty)12 YType (org.springframework.ide.vscode.commons.yaml.schema.YType)9 YTypeUtil (org.springframework.ide.vscode.commons.yaml.schema.YTypeUtil)7 ImmutableList (com.google.common.collect.ImmutableList)6 Collection (java.util.Collection)6 List (java.util.List)6 CollectorUtil (org.springframework.ide.vscode.commons.util.CollectorUtil)6 Collectors (java.util.stream.Collectors)5 DynamicSchemaContext (org.springframework.ide.vscode.commons.yaml.schema.DynamicSchemaContext)5 Map (java.util.Map)4 SnippetBuilder (org.springframework.ide.vscode.commons.languageserver.util.SnippetBuilder)4 YamlPath (org.springframework.ide.vscode.commons.yaml.path.YamlPath)4 Supplier (com.google.common.base.Supplier)3 Set (java.util.Set)3 StringUtil (org.springframework.ide.vscode.commons.util.StringUtil)3 YamlIndentUtil (org.springframework.ide.vscode.commons.yaml.util.YamlIndentUtil)3 ArrayList (java.util.ArrayList)2 IProblemCollector (org.springframework.ide.vscode.commons.languageserver.reconcile.IProblemCollector)2 PlaceHolderString (org.springframework.ide.vscode.commons.languageserver.util.PlaceHolderString)2 Log (org.springframework.ide.vscode.commons.util.Log)2