Search in sources :

Example 1 with LoopSection

use of com.redhat.qute.parser.template.sections.LoopSection in project quarkus-ls by redhat-developer.

the class QuteDiagnostics method validateDataModel.

private void validateDataModel(Node parent, Template template, QuteValidationSettings validationSettings, ResolvingJavaTypeContext resolvingJavaTypeContext, ResolutionContext currentContext, List<Diagnostic> diagnostics) {
    ResolutionContext previousContext = currentContext;
    List<Node> children = parent.getChildren();
    for (Node node : children) {
        switch(node.getKind()) {
            case ParameterDeclaration:
                {
                    ParameterDeclaration parameter = (ParameterDeclaration) node;
                    String javaTypeToResolve = parameter.getJavaType();
                    if (!StringUtils.isEmpty(javaTypeToResolve)) {
                        String projectUri = template.getProjectUri();
                        if (projectUri != null) {
                            List<JavaTypeRangeOffset> classNameRanges = parameter.getJavaTypeNameRanges();
                            for (RangeOffset classNameRange : classNameRanges) {
                                String className = template.getText(classNameRange);
                                ResolvedJavaTypeInfo resolvedJavaType = resolveJavaType(className, projectUri, resolvingJavaTypeContext);
                                if (resolvedJavaType == null) {
                                    // Java type doesn't exist
                                    Range range = QutePositionUtility.createRange(classNameRange, template);
                                    Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, QuteErrorCode.UnknownType, className);
                                    diagnostics.add(diagnostic);
                                } else if (!isResolvingJavaType(resolvedJavaType)) {
                                    currentContext.put(javaTypeToResolve, resolvedJavaType);
                                }
                            }
                        }
                    }
                    break;
                }
            case Section:
                {
                    Section section = (Section) node;
                    if (canChangeContext(section)) {
                        currentContext = new ResolutionContext(currentContext);
                    }
                    List<Parameter> parameters = section.getParameters();
                    // validate expression parameters
                    for (Parameter parameter : parameters) {
                        Expression expression = parameter.getJavaTypeExpression();
                        if (expression != null) {
                            ResolvedJavaTypeInfo result = validateExpression(expression, section, template, validationSettings, previousContext, resolvingJavaTypeContext, diagnostics);
                            switch(section.getSectionKind()) {
                                case FOR:
                                case EACH:
                                    String alias = ((LoopSection) section).getAlias();
                                    currentContext.put(alias, result);
                                    break;
                                case WITH:
                                    currentContext.setWithObject(result);
                                    break;
                                case LET:
                                case SET:
                                    currentContext.put(parameter.getName(), result);
                                    break;
                                default:
                            }
                        }
                    }
                    switch(section.getSectionKind()) {
                        case INCLUDE:
                            validateIncludeSection((IncludeSection) section, diagnostics);
                            break;
                        default:
                            validateSectionTag(section, template, resolvingJavaTypeContext, diagnostics);
                    }
                    break;
                }
            case Expression:
                {
                    validateExpression((Expression) node, null, template, validationSettings, previousContext, resolvingJavaTypeContext, diagnostics);
                    break;
                }
            default:
        }
        validateDataModel(node, template, validationSettings, resolvingJavaTypeContext, currentContext, diagnostics);
    }
}
Also used : Node(com.redhat.qute.parser.template.Node) ResolvedJavaTypeInfo(com.redhat.qute.commons.ResolvedJavaTypeInfo) DiagnosticDataFactory.createDiagnostic(com.redhat.qute.services.diagnostics.DiagnosticDataFactory.createDiagnostic) Diagnostic(org.eclipse.lsp4j.Diagnostic) Range(org.eclipse.lsp4j.Range) IncludeSection(com.redhat.qute.parser.template.sections.IncludeSection) LoopSection(com.redhat.qute.parser.template.sections.LoopSection) Section(com.redhat.qute.parser.template.Section) Expression(com.redhat.qute.parser.template.Expression) JavaTypeRangeOffset(com.redhat.qute.parser.template.ParameterDeclaration.JavaTypeRangeOffset) RangeOffset(com.redhat.qute.parser.template.RangeOffset) Parameter(com.redhat.qute.parser.template.Parameter) IncludeSection(com.redhat.qute.parser.template.sections.IncludeSection) List(java.util.List) ArrayList(java.util.ArrayList) ParameterDeclaration(com.redhat.qute.parser.template.ParameterDeclaration)

Example 2 with LoopSection

use of com.redhat.qute.parser.template.sections.LoopSection in project quarkus-ls by redhat-developer.

the class QuteCompletionsForExpression method doCompleteExpressionForObjectPartWithParentNodes.

private void doCompleteExpressionForObjectPartWithParentNodes(Node part, Node node, Range range, int offset, String projectUri, Set<String> existingVars, QuteCompletionSettings completionSettings, QuteFormattingSettings formattingSettings, CompletionList list) {
    Section section = node != null ? node.getParentSection() : null;
    if (section == null) {
        return;
    }
    if (section.getKind() == NodeKind.Section) {
        boolean collect = true;
        if (section.getSectionKind() == SectionKind.FOR || section.getSectionKind() == SectionKind.EACH) {
            LoopSection iterableSection = ((LoopSection) section);
            if (iterableSection.isInElseBlock(offset)) {
                // Completion is triggered after a #else inside a #for, we don't provide
                // completion for metadata or aliases
                collect = false;
            }
        }
        if (collect) {
            // 1) Completion for metadata section
            List<SectionMetadata> metadatas = section.getMetadata();
            for (SectionMetadata metadata : metadatas) {
                String name = metadata.getName();
                if (!existingVars.contains(name)) {
                    existingVars.add(name);
                    CompletionItem item = new CompletionItem();
                    item.setLabel(name);
                    item.setKind(CompletionItemKind.Keyword);
                    // Display metadata section (ex : count for #each) after declared objects
                    item.setSortText("Za" + name);
                    TextEdit textEdit = new TextEdit(range, name);
                    item.setTextEdit(Either.forLeft(textEdit));
                    item.setDetail(metadata.getDescription());
                    list.getItems().add(item);
                }
            }
            // 2) Completion for aliases section
            switch(section.getSectionKind()) {
                case EACH:
                case FOR:
                    LoopSection iterableSection = ((LoopSection) section);
                    // Completion for iterable section like #each, #for
                    String alias = iterableSection.getAlias();
                    if (!StringUtils.isEmpty(alias)) {
                        if (!existingVars.contains(alias)) {
                            existingVars.add(alias);
                            CompletionItem item = new CompletionItem();
                            item.setLabel(alias);
                            item.setKind(CompletionItemKind.Reference);
                            TextEdit textEdit = new TextEdit(range, alias);
                            item.setTextEdit(Either.forLeft(textEdit));
                            list.getItems().add(item);
                        }
                    }
                    break;
                case LET:
                case SET:
                    // completion for parameters coming from #let, #set
                    List<Parameter> parameters = section.getParameters();
                    if (parameters != null) {
                        for (Parameter parameter : parameters) {
                            String parameterName = parameter.getName();
                            if (!existingVars.contains(parameterName)) {
                                existingVars.add(parameterName);
                                CompletionItem item = new CompletionItem();
                                item.setLabel(parameterName);
                                item.setKind(CompletionItemKind.Reference);
                                TextEdit textEdit = new TextEdit(range, parameterName);
                                item.setTextEdit(Either.forLeft(textEdit));
                                list.getItems().add(item);
                            }
                        }
                    }
                    break;
                case WITH:
                    // Completion for properties/methods of with object from #with
                    Parameter object = ((WithSection) section).getObjectParameter();
                    if (object != null) {
                        ResolvedJavaTypeInfo withJavaTypeInfo = javaCache.resolveJavaType(object, projectUri).getNow(null);
                        if (withJavaTypeInfo != null) {
                            fillCompletionFields(withJavaTypeInfo, range, projectUri, existingVars, list);
                            fillCompletionMethods(withJavaTypeInfo, range, projectUri, completionSettings, formattingSettings, existingVars, new HashSet<>(), list);
                        }
                    }
                    break;
                default:
            }
        }
    }
    doCompleteExpressionForObjectPartWithParentNodes(part, section, range, offset, projectUri, existingVars, completionSettings, formattingSettings, list);
}
Also used : WithSection(com.redhat.qute.parser.template.sections.WithSection) ResolvedJavaTypeInfo(com.redhat.qute.commons.ResolvedJavaTypeInfo) WithSection(com.redhat.qute.parser.template.sections.WithSection) LoopSection(com.redhat.qute.parser.template.sections.LoopSection) Section(com.redhat.qute.parser.template.Section) LoopSection(com.redhat.qute.parser.template.sections.LoopSection) CompletionItem(org.eclipse.lsp4j.CompletionItem) TextEdit(org.eclipse.lsp4j.TextEdit) SectionMetadata(com.redhat.qute.parser.template.SectionMetadata) Parameter(com.redhat.qute.parser.template.Parameter) ExtendedDataModelParameter(com.redhat.qute.project.datamodel.ExtendedDataModelParameter)

Example 3 with LoopSection

use of com.redhat.qute.parser.template.sections.LoopSection in project quarkus-ls by redhat-developer.

the class ObjectPart method resolveJavaType.

public JavaTypeInfoProvider resolveJavaType() {
    Template template = super.getOwnerTemplate();
    String partName = getPartName();
    boolean hasNamespace = getNamespace() != null;
    if (hasNamespace) {
        // ex : {data:item}
        return template.findWithNamespace(this);
    }
    // ex : {item}
    // Loop for parent section to discover the class name
    Section section = super.getParentSection();
    while (section != null) {
        switch(section.getSectionKind()) {
            case EACH:
            case FOR:
                LoopSection iterableSection = (LoopSection) section;
                if (!iterableSection.isInElseBlock(getStart())) {
                    String alias = iterableSection.getAlias();
                    if (partName.equals(alias)) {
                        return iterableSection.getIterableParameter();
                    }
                }
                break;
            case LET:
            case SET:
                List<Parameter> parameters = section.getParameters();
                for (Parameter parameter : parameters) {
                    if (partName.equals(parameter.getName())) {
                        return parameter;
                    }
                }
                break;
            default:
        }
        // ex : count for #each
        JavaTypeInfoProvider metadata = section.getMetadata(partName);
        if (metadata != null) {
            return metadata;
        }
        section = section.getParentSection();
    }
    // - from @CheckedTemplate
    return template.findInInitialDataModel(this);
}
Also used : JavaTypeInfoProvider(com.redhat.qute.parser.template.JavaTypeInfoProvider) LoopSection(com.redhat.qute.parser.template.sections.LoopSection) Parameter(com.redhat.qute.parser.template.Parameter) LoopSection(com.redhat.qute.parser.template.sections.LoopSection) Section(com.redhat.qute.parser.template.Section) Template(com.redhat.qute.parser.template.Template)

Example 4 with LoopSection

use of com.redhat.qute.parser.template.sections.LoopSection in project quarkus-ls by redhat-developer.

the class QuteHover method doHoverForParameter.

private CompletableFuture<Hover> doHoverForParameter(Parameter parameter, Template template, HoverRequest hoverRequest) {
    int offset = hoverRequest.getOffset();
    if (parameter.isInName(offset)) {
        // A parameter name is hovered
        if (parameter.getOwnerSection() != null && (parameter.getOwnerSection().getSectionKind() == SectionKind.FOR || parameter.getOwnerSection().getSectionKind() == SectionKind.EACH)) {
            // a parameter from #for section is hovered
            LoopSection iterableSection = (LoopSection) parameter.getOwnerSection();
            if (iterableSection.isInAlias(offset)) {
                Parameter iterableParameter = iterableSection.getIterableParameter();
                if (iterableParameter != null) {
                    boolean hasMarkdown = hoverRequest.canSupportMarkupKind(MarkupKind.MARKDOWN);
                    String projectUri = template.getProjectUri();
                    Part iterablePart = iterableParameter.getJavaTypeExpression().getLastPart();
                    return // 
                    javaCache.resolveJavaType(iterablePart, projectUri).thenCompose(resolvedJavaType -> {
                        if (resolvedJavaType != null && resolvedJavaType.isIterable()) {
                            return // 
                            javaCache.resolveJavaType(resolvedJavaType.getIterableOf(), projectUri).thenApply(resolvedIterableOf -> {
                                MarkupContent content = DocumentationUtils.getDocumentation(resolvedIterableOf, hasMarkdown);
                                Range range = QutePositionUtility.createRange(parameter);
                                return new Hover(content, range);
                            });
                        }
                        return NO_HOVER;
                    });
                }
            }
        } else {
            // Other parameter
            // Check if part is a literal (ex: true, null, 123, 'abc', etc)
            Expression expression = parameter.getJavaTypeExpression();
            if (expression != null) {
                String projectUri = template.getProjectUri();
                String literalJavaType = expression.getLiteralJavaType();
                if (literalJavaType != null) {
                    return // 
                    javaCache.resolveJavaType(literalJavaType, projectUri).thenApply(resolvedJavaType -> {
                        if (resolvedJavaType != null) {
                            boolean hasMarkdown = hoverRequest.canSupportMarkupKind(MarkupKind.MARKDOWN);
                            MarkupContent content = DocumentationUtils.getDocumentation(resolvedJavaType, hasMarkdown);
                            Range range = QutePositionUtility.createRange(parameter);
                            return new Hover(content, range);
                        }
                        return null;
                    });
                }
                return // 
                javaCache.resolveJavaType(parameter, projectUri).thenApply(resolvedJavaType -> {
                    if (resolvedJavaType != null) {
                        boolean hasMarkdown = hoverRequest.canSupportMarkupKind(MarkupKind.MARKDOWN);
                        MarkupContent content = DocumentationUtils.getDocumentation(resolvedJavaType, hasMarkdown);
                        Range range = QutePositionUtility.createRange(parameter);
                        return new Hover(content, range);
                    }
                    return null;
                });
            }
        }
    }
    return NO_HOVER;
}
Also used : LoopSection(com.redhat.qute.parser.template.sections.LoopSection) Expression(com.redhat.qute.parser.template.Expression) NamespacePart(com.redhat.qute.parser.expression.NamespacePart) Part(com.redhat.qute.parser.expression.Part) Hover(org.eclipse.lsp4j.Hover) Parameter(com.redhat.qute.parser.template.Parameter) Range(org.eclipse.lsp4j.Range) MarkupContent(org.eclipse.lsp4j.MarkupContent)

Example 5 with LoopSection

use of com.redhat.qute.parser.template.sections.LoopSection in project quarkus-ls by redhat-developer.

the class QuteSearchUtils method searchDeclaredObjectInParameter.

private static Parameter searchDeclaredObjectInParameter(ObjectPart part, CancelChecker cancelChecker) {
    String partName = part.getPartName();
    Node parent = part.getParentSection();
    while (parent != null) {
        if (parent.getKind() == NodeKind.Section) {
            Section section = (Section) parent;
            switch(section.getSectionKind()) {
                case EACH:
                case FOR:
                    LoopSection iterableSection = (LoopSection) section;
                    if (!iterableSection.isInElseBlock(part.getStart())) {
                        String alias = iterableSection.getAlias();
                        if (partName.equals(alias) || section.isMetadata(partName)) {
                            // - or the metadata of the section (ex : item_count)
                            return iterableSection.getAliasParameter();
                        }
                    }
                    break;
                case LET:
                case SET:
                    List<Parameter> parameters = section.getParameters();
                    for (Parameter parameter : parameters) {
                        if (partName.equals(parameter.getName())) {
                            return parameter;
                        }
                    }
                    break;
                default:
            }
        }
        parent = parent.getParent();
    }
    return null;
}
Also used : LoopSection(com.redhat.qute.parser.template.sections.LoopSection) Node(com.redhat.qute.parser.template.Node) Parameter(com.redhat.qute.parser.template.Parameter) LoopSection(com.redhat.qute.parser.template.sections.LoopSection) BaseWhenSection(com.redhat.qute.parser.template.sections.BaseWhenSection) WithSection(com.redhat.qute.parser.template.sections.WithSection) Section(com.redhat.qute.parser.template.Section)

Aggregations

Parameter (com.redhat.qute.parser.template.Parameter)5 LoopSection (com.redhat.qute.parser.template.sections.LoopSection)5 Section (com.redhat.qute.parser.template.Section)4 ResolvedJavaTypeInfo (com.redhat.qute.commons.ResolvedJavaTypeInfo)2 Expression (com.redhat.qute.parser.template.Expression)2 Node (com.redhat.qute.parser.template.Node)2 WithSection (com.redhat.qute.parser.template.sections.WithSection)2 Range (org.eclipse.lsp4j.Range)2 NamespacePart (com.redhat.qute.parser.expression.NamespacePart)1 Part (com.redhat.qute.parser.expression.Part)1 JavaTypeInfoProvider (com.redhat.qute.parser.template.JavaTypeInfoProvider)1 ParameterDeclaration (com.redhat.qute.parser.template.ParameterDeclaration)1 JavaTypeRangeOffset (com.redhat.qute.parser.template.ParameterDeclaration.JavaTypeRangeOffset)1 RangeOffset (com.redhat.qute.parser.template.RangeOffset)1 SectionMetadata (com.redhat.qute.parser.template.SectionMetadata)1 Template (com.redhat.qute.parser.template.Template)1 BaseWhenSection (com.redhat.qute.parser.template.sections.BaseWhenSection)1 IncludeSection (com.redhat.qute.parser.template.sections.IncludeSection)1 ExtendedDataModelParameter (com.redhat.qute.project.datamodel.ExtendedDataModelParameter)1 DiagnosticDataFactory.createDiagnostic (com.redhat.qute.services.diagnostics.DiagnosticDataFactory.createDiagnostic)1