Search in sources :

Example 1 with Section

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

the class QuteCompletions method doComplete.

/**
 * Returns completion list for the given position
 *
 * @param template           the Qute template
 * @param position           the position where completion was triggered
 * @param completionSettings the completion settings.
 * @param formattingSettings the formatting settings.
 * @param cancelChecker      the cancel checker
 * @return completion list for the given position
 */
public CompletableFuture<CompletionList> doComplete(Template template, Position position, QuteCompletionSettings completionSettings, QuteFormattingSettings formattingSettings, CancelChecker cancelChecker) {
    CompletionRequest completionRequest = null;
    try {
        completionRequest = new CompletionRequest(template, position, completionSettings, formattingSettings);
    } catch (BadLocationException e) {
        LOGGER.log(Level.SEVERE, "Creation of CompletionRequest failed", e);
        return EMPTY_FUTURE_COMPLETION;
    }
    Node node = completionRequest.getNode();
    if (node == null) {
        return EMPTY_FUTURE_COMPLETION;
    }
    String text = template.getText();
    int offset = completionRequest.getOffset();
    if (node.getKind() == NodeKind.Expression || node.getKind() == NodeKind.ExpressionParts || node.getKind() == NodeKind.ExpressionPart) {
        Expression expression = null;
        Node nodeExpression = null;
        if (node.getKind() == NodeKind.Expression) {
            expression = (Expression) node;
        } else if (node.getKind() == NodeKind.ExpressionParts) {
            nodeExpression = node;
            expression = ((Parts) node).getParent();
        } else if (node.getKind() == NodeKind.ExpressionPart) {
            nodeExpression = node;
            expression = ((Part) node).getParent().getParent();
        }
        return completionForExpression.doCompleteExpression(completionRequest, expression, nodeExpression, template, offset, completionSettings, formattingSettings, cancelChecker);
    } else if (node.getKind() == NodeKind.Text) {
        // The completion is triggered in text node (before node)
        Section parent = node.getParentSection();
        if (parent != null && (parent.isInEndTagName(offset))) {
            // The completion is triggered inside end tag
            return EMPTY_FUTURE_COMPLETION;
        }
        // The completion is triggered in text node
        // Check if completion is triggered after a start bracket character and if it's
        // a valid expression
        int nbBrackets = 0;
        int bracketOffset = offset - 1;
        char previousChar = text.charAt(bracketOffset);
        if (previousChar == '#') {
            // {#
            bracketOffset--;
        }
        while (bracketOffset >= 0 && text.charAt(bracketOffset) == '{') {
            bracketOffset--;
            nbBrackets++;
        }
        if (nbBrackets > 0) {
            if (nbBrackets % 2 != 0) {
                // The completion is triggered in text node after bracket '{' character
                return completionForExpression.doCompleteExpression(completionRequest, null, node, template, offset, completionSettings, formattingSettings, cancelChecker);
            }
            return EMPTY_FUTURE_COMPLETION;
        }
    } else if (node.getKind() == NodeKind.ParameterDeclaration) {
        return completionsForParameterDeclaration.doCollectJavaClassesSuggestions((ParameterDeclaration) node, template, offset, completionSettings);
    } else if (node.getKind() == NodeKind.Section) {
        // {#|}
        return completionForTagSection.doCompleteTagSection(completionRequest, completionSettings, formattingSettings, cancelChecker);
    }
    return collectSnippetSuggestions(completionRequest);
}
Also used : Expression(com.redhat.qute.parser.template.Expression) QuteCompletionsForExpression(com.redhat.qute.services.completions.QuteCompletionsForExpression) Parts(com.redhat.qute.parser.expression.Parts) Part(com.redhat.qute.parser.expression.Part) Node(com.redhat.qute.parser.template.Node) CompletionRequest(com.redhat.qute.services.completions.CompletionRequest) QuteCompletionForTagSection(com.redhat.qute.services.completions.QuteCompletionForTagSection) Section(com.redhat.qute.parser.template.Section) BadLocationException(com.redhat.qute.ls.commons.BadLocationException)

Example 2 with Section

use of com.redhat.qute.parser.template.Section 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 3 with Section

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

the class QuteDocumentLink method findDocumentLinks.

private void findDocumentLinks(Node node, Template template, List<DocumentLink> links) {
    List<Node> children = node.getChildren();
    for (Node child : children) {
        if (child.getKind() == NodeKind.Section) {
            Section section = (Section) child;
            if (section.getSectionKind() == SectionKind.INCLUDE) {
                // #include section case:
                IncludeSection includeSection = (IncludeSection) section;
                // {#include base.qute.html}
                // In this case 'base.qute.html' is a document link
                Parameter includedTemplateId = includeSection.getParameterAtIndex(0);
                if (includedTemplateId != null) {
                    Range range = QutePositionUtility.createRange(includedTemplateId.getStart(), includedTemplateId.getEnd(), template);
                    if (range != null) {
                        Path templateFile = includeSection.getReferencedTemplateFile();
                        if (templateFile != null) {
                            String target = templateFile.toUri().toString();
                            links.add(new DocumentLink(range, target != null ? target : ""));
                        }
                    }
                }
            }
        }
        findDocumentLinks(child, template, links);
    }
}
Also used : Path(java.nio.file.Path) Node(com.redhat.qute.parser.template.Node) IncludeSection(com.redhat.qute.parser.template.sections.IncludeSection) Parameter(com.redhat.qute.parser.template.Parameter) Range(org.eclipse.lsp4j.Range) IncludeSection(com.redhat.qute.parser.template.sections.IncludeSection) Section(com.redhat.qute.parser.template.Section) DocumentLink(org.eclipse.lsp4j.DocumentLink)

Example 4 with Section

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

the class QuteHover method doHoverForSection.

private CompletableFuture<Hover> doHoverForSection(Section section, Template template, HoverRequest hoverRequest, CancelChecker cancelChecker) {
    if (section.hasTag()) {
        // the section defines a tag (e : {#for
        String tagName = section.getTag();
        if (section.getSectionKind() == SectionKind.CUSTOM) {
            // custom tag: search information about user tag
            QuteProject project = template.getProject();
            if (project != null) {
                UserTag userTag = project.findUserTag(tagName);
                if (userTag != null) {
                    Range range = createSectionTagRange(section, hoverRequest);
                    if (range != null) {
                        boolean hasMarkdown = hoverRequest.canSupportMarkupKind(MarkupKind.MARKDOWN);
                        MarkupContent content = DocumentationUtils.getDocumentation(userTag, hasMarkdown);
                        Hover hover = new Hover(content, range);
                        return CompletableFuture.completedFuture(hover);
                    }
                }
            }
        } else {
            // core tag like #for, #if, etc: display document hover for the section
            Optional<Snippet> snippetSection = // 
            snippetRegistryProvider.getSnippetRegistry().getSnippets().stream().filter(// 
            snippet -> tagName.equals(snippet.getLabel())).findFirst();
            if (snippetSection.isPresent()) {
                Snippet snippet = snippetSection.get();
                Range range = createSectionTagRange(section, hoverRequest);
                if (range != null) {
                    boolean hasMarkdown = hoverRequest.canSupportMarkupKind(MarkupKind.MARKDOWN);
                    MarkupContent content = DocumentationUtils.getDocumentation(snippet, hasMarkdown);
                    Hover hover = new Hover(content, range);
                    return CompletableFuture.completedFuture(hover);
                }
            }
        }
    }
    return NO_HOVER;
}
Also used : Template(com.redhat.qute.parser.template.Template) LoopSection(com.redhat.qute.parser.template.sections.LoopSection) MarkupKind(org.eclipse.lsp4j.MarkupKind) UserTagUtils(com.redhat.qute.utils.UserTagUtils) SectionMetadata(com.redhat.qute.parser.template.SectionMetadata) QutePositionUtility(com.redhat.qute.utils.QutePositionUtility) CompletableFuture(java.util.concurrent.CompletableFuture) Range(org.eclipse.lsp4j.Range) QuteProject(com.redhat.qute.project.QuteProject) Hover(org.eclipse.lsp4j.Hover) SnippetRegistryProvider(com.redhat.qute.ls.commons.snippets.SnippetRegistryProvider) Level(java.util.logging.Level) Parameter(com.redhat.qute.parser.template.Parameter) JavaDataModelCache(com.redhat.qute.project.datamodel.JavaDataModelCache) UserTag(com.redhat.qute.project.tags.UserTag) SectionKind(com.redhat.qute.parser.template.SectionKind) Expression(com.redhat.qute.parser.template.Expression) Section(com.redhat.qute.parser.template.Section) Parts(com.redhat.qute.parser.expression.Parts) Position(org.eclipse.lsp4j.Position) JavaMemberInfo(com.redhat.qute.commons.JavaMemberInfo) Snippet(com.redhat.qute.ls.commons.snippets.Snippet) DocumentationUtils(com.redhat.qute.utils.DocumentationUtils) MarkupContent(org.eclipse.lsp4j.MarkupContent) NamespacePart(com.redhat.qute.parser.expression.NamespacePart) Node(com.redhat.qute.parser.template.Node) JavaTypeInfo(com.redhat.qute.commons.JavaTypeInfo) Logger(java.util.logging.Logger) CancelChecker(org.eclipse.lsp4j.jsonrpc.CancelChecker) HoverRequest(com.redhat.qute.services.hover.HoverRequest) BadLocationException(com.redhat.qute.ls.commons.BadLocationException) Part(com.redhat.qute.parser.expression.Part) ParameterDeclaration(com.redhat.qute.parser.template.ParameterDeclaration) SharedSettings(com.redhat.qute.settings.SharedSettings) RangeOffset(com.redhat.qute.parser.template.RangeOffset) ResolvedJavaTypeInfo(com.redhat.qute.commons.ResolvedJavaTypeInfo) Optional(java.util.Optional) Hover(org.eclipse.lsp4j.Hover) QuteProject(com.redhat.qute.project.QuteProject) Snippet(com.redhat.qute.ls.commons.snippets.Snippet) UserTag(com.redhat.qute.project.tags.UserTag) Range(org.eclipse.lsp4j.Range) MarkupContent(org.eclipse.lsp4j.MarkupContent)

Example 5 with Section

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

the class JavaDataModelCache method resolveJavaType.

private CompletableFuture<ResolvedJavaTypeInfo> resolveJavaType(ObjectPart objectPart, String projectUri, boolean nullIfDontMatchWithIterable) {
    CompletableFuture<ResolvedJavaTypeInfo> future = null;
    JavaTypeInfoProvider javaTypeInfo = objectPart.resolveJavaType();
    if (javaTypeInfo == null) {
        return RESOLVED_JAVA_TYPE_INFO_NULL_FUTURE;
    }
    String javaType = javaTypeInfo.getJavaType();
    if (StringUtils.isEmpty(javaType)) {
        Expression expression = javaTypeInfo.getJavaTypeExpression();
        if (expression != null) {
            String literalJavaType = expression.getLiteralJavaType();
            if (literalJavaType != null) {
                future = resolveJavaType(literalJavaType, projectUri);
            } else {
                Part lastPart = expression.getLastPart();
                if (lastPart == null) {
                    return RESOLVED_JAVA_TYPE_INFO_NULL_FUTURE;
                }
                future = resolveJavaType(lastPart, projectUri);
            }
        }
    }
    if (future == null) {
        future = resolveJavaType(javaType, projectUri);
    }
    Node node = javaTypeInfo.getJavaTypeOwnerNode();
    Section section = getOwnerSection(node);
    if (section != null) {
        if (section.isIterable()) {
            future = // 
            future.thenCompose(resolvedType -> {
                if (resolvedType == null) {
                    return RESOLVED_JAVA_TYPE_INFO_NULL_FUTURE;
                }
                if (!resolvedType.isIterable()) {
                    if (resolvedType.isInteger()) {
                        // {/for}
                        return resolveJavaType(resolvedType.getName(), projectUri);
                    }
                    if (nullIfDontMatchWithIterable) {
                        // {item.|}
                        return RESOLVED_JAVA_TYPE_INFO_NULL_FUTURE;
                    }
                }
                // valid case
                // Ex:
                // {@java.util.List<org.acme.Item> items}
                // {#for item in items}
                // {item.|}
                // Here
                // - resolvedType = java.util.List<org.acme.Item>
                // - iterTypeName = org.acme.Item
                // Resolve org.acme.Item
                String iterTypeName = resolvedType.getIterableOf();
                return resolveJavaType(iterTypeName, projectUri);
            });
        }
    }
    return future;
}
Also used : Template(com.redhat.qute.parser.template.Template) ValueResolver(com.redhat.qute.project.datamodel.resolvers.ValueResolver) MethodValueResolver(com.redhat.qute.project.datamodel.resolvers.MethodValueResolver) ObjectPart(com.redhat.qute.parser.expression.ObjectPart) StringUtils(com.redhat.qute.utils.StringUtils) CompletableFuture(java.util.concurrent.CompletableFuture) QuteJavaTypesParams(com.redhat.qute.commons.QuteJavaTypesParams) NodeKind(com.redhat.qute.parser.template.NodeKind) Parameter(com.redhat.qute.parser.template.Parameter) QuteProjectRegistry(com.redhat.qute.project.QuteProjectRegistry) Expression(com.redhat.qute.parser.template.Expression) Section(com.redhat.qute.parser.template.Section) Location(org.eclipse.lsp4j.Location) Parts(com.redhat.qute.parser.expression.Parts) JavaMemberInfo(com.redhat.qute.commons.JavaMemberInfo) InvalidMethodReason(com.redhat.qute.commons.InvalidMethodReason) NamespaceResolverInfo(com.redhat.qute.commons.datamodel.resolvers.NamespaceResolverInfo) Node(com.redhat.qute.parser.template.Node) JavaTypeInfo(com.redhat.qute.commons.JavaTypeInfo) JavaMemberResult(com.redhat.qute.project.JavaMemberResult) JavaTypeInfoProvider(com.redhat.qute.parser.template.JavaTypeInfoProvider) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) Part(com.redhat.qute.parser.expression.Part) ResolvedJavaTypeInfo(com.redhat.qute.commons.ResolvedJavaTypeInfo) JavaElementInfo(com.redhat.qute.commons.JavaElementInfo) QuteJavaDefinitionParams(com.redhat.qute.commons.QuteJavaDefinitionParams) JavaTypeInfoProvider(com.redhat.qute.parser.template.JavaTypeInfoProvider) Expression(com.redhat.qute.parser.template.Expression) ObjectPart(com.redhat.qute.parser.expression.ObjectPart) Part(com.redhat.qute.parser.expression.Part) Node(com.redhat.qute.parser.template.Node) ResolvedJavaTypeInfo(com.redhat.qute.commons.ResolvedJavaTypeInfo) Section(com.redhat.qute.parser.template.Section)

Aggregations

Section (com.redhat.qute.parser.template.Section)18 Node (com.redhat.qute.parser.template.Node)15 Parameter (com.redhat.qute.parser.template.Parameter)11 LoopSection (com.redhat.qute.parser.template.sections.LoopSection)8 Range (org.eclipse.lsp4j.Range)7 Expression (com.redhat.qute.parser.template.Expression)6 BadLocationException (com.redhat.qute.ls.commons.BadLocationException)5 ResolvedJavaTypeInfo (com.redhat.qute.commons.ResolvedJavaTypeInfo)4 Part (com.redhat.qute.parser.expression.Part)4 IncludeSection (com.redhat.qute.parser.template.sections.IncludeSection)4 QuteProject (com.redhat.qute.project.QuteProject)4 Parts (com.redhat.qute.parser.expression.Parts)3 JavaTypeInfoProvider (com.redhat.qute.parser.template.JavaTypeInfoProvider)3 ParameterDeclaration (com.redhat.qute.parser.template.ParameterDeclaration)3 Template (com.redhat.qute.parser.template.Template)3 WithSection (com.redhat.qute.parser.template.sections.WithSection)3 QuteIndex (com.redhat.qute.project.indexing.QuteIndex)3 List (java.util.List)3 JavaMemberInfo (com.redhat.qute.commons.JavaMemberInfo)2 JavaTypeInfo (com.redhat.qute.commons.JavaTypeInfo)2