Search in sources :

Example 6 with Expression

use of com.redhat.qute.parser.template.Expression 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)

Example 7 with Expression

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

the class QuteCodeActions method doCodeActionsForUndefinedObject.

private static void doCodeActionsForUndefinedObject(Template template, Diagnostic diagnostic, QuteErrorCode errorCode, List<CodeAction> codeActions) {
    try {
        String varName = null;
        boolean isIterable = false;
        JsonObject data = (JsonObject) diagnostic.getData();
        if (data != null) {
            varName = data.get(DIAGNOSTIC_DATA_NAME).getAsString();
            isIterable = data.get(DIAGNOSTIC_DATA_ITERABLE).getAsBoolean();
        } else {
            int offset = template.offsetAt(diagnostic.getRange().getStart());
            Node node = template.findNodeAt(offset);
            node = QutePositionUtility.findBestNode(offset, node);
            if (node.getKind() == NodeKind.Expression) {
                Expression expression = (Expression) node;
                ObjectPart part = expression.getObjectPart();
                if (part != null) {
                    varName = part.getPartName();
                }
            }
        }
        if (varName != null) {
            TextDocument document = template.getTextDocument();
            String lineDelimiter = document.lineDelimiter(0);
            String title = MessageFormat.format(UNDEFINED_OBJECT_CODEACTION_TITLE, varName);
            Position position = new Position(0, 0);
            StringBuilder insertText = new StringBuilder("{@");
            if (isIterable) {
                insertText.append("java.util.List");
            } else {
                insertText.append("java.lang.String");
            }
            insertText.append(" ");
            insertText.append(varName);
            insertText.append("}");
            insertText.append(lineDelimiter);
            CodeAction insertParameterDeclarationQuickFix = CodeActionFactory.insert(title, position, insertText.toString(), document, diagnostic);
            codeActions.add(insertParameterDeclarationQuickFix);
            // CodeAction to set validation severity to ignore
            doCodeActionToSetIgnoreSeverity(template, Collections.singletonList(diagnostic), errorCode, codeActions, UNDEFINED_OBJECT_SEVERITY_SETTING);
        }
    } catch (BadLocationException e) {
    }
}
Also used : TextDocument(com.redhat.qute.ls.commons.TextDocument) ObjectPart(com.redhat.qute.parser.expression.ObjectPart) Expression(com.redhat.qute.parser.template.Expression) Position(org.eclipse.lsp4j.Position) Node(com.redhat.qute.parser.template.Node) CodeAction(org.eclipse.lsp4j.CodeAction) JsonObject(com.google.gson.JsonObject) BadLocationException(com.redhat.qute.ls.commons.BadLocationException)

Example 8 with Expression

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

the class QutePositionUtility method findBestNode.

/**
 * Find the best node from the given expression at the given offset.
 *
 * @param expression the expression node.
 * @param offset     the offset.
 *
 * @return the best node from the given expression at the given offset.
 */
private static Node findBestNode(Expression expression, int offset) {
    Node expressionNode = expression.findNodeExpressionAt(offset);
    if (expressionNode != null) {
        if (expressionNode instanceof MethodPart) {
            MethodPart method = (MethodPart) expressionNode;
            Parameter parameter = method.getParameterAtOffset(offset);
            if (parameter != null) {
                Expression parameterExpression = parameter.getJavaTypeExpression();
                if (parameterExpression != null) {
                    return findBestNode(parameterExpression, offset);
                }
                return parameter;
            }
        }
        return expressionNode;
    }
    return expression;
}
Also used : Expression(com.redhat.qute.parser.template.Expression) Node(com.redhat.qute.parser.template.Node) Parameter(com.redhat.qute.parser.template.Parameter) MethodPart(com.redhat.qute.parser.expression.MethodPart)

Example 9 with Expression

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

the class QuteSearchUtils method tryToCollectObjectParts.

/**
 * Try to collect all object parts from the given expression
 * <code>nodeExpr</code> which matches the given part name
 * <code>partName</code>.
 *
 * @param partName  the part name.
 * @param matcher   the matcher strategy.
 * @param nodeExpr  the Qute node expression
 * @param collector the node collector.
 *
 * @return true if the given nodeExpr reference the part name as object part and
 *         false otherwise.
 */
private static boolean tryToCollectObjectParts(String partName, PartNameMatcher matcher, Node nodeExpr, BiConsumer<Node, Range> collector) {
    switch(nodeExpr.getKind()) {
        case Expression:
            {
                Expression expression = (Expression) nodeExpr;
                boolean result = false;
                List<Node> nodes = expression.getExpressionContent();
                for (Node node : nodes) {
                    // ex : partName=item
                    // node expression can be
                    // 1) a simple expression:
                    // --> {item_count} --> [ObjectPart=item_count]
                    // --> {item.name} --> [ObjectPart=item, PropertyPart=name)
                    // --> {item.getName()} --> [ObjectPart=item, MethodPart=getName())
                    // In those cases, one object part will be collected =>{|item|_count},
                    // {|item|.name}, {|item|.getName()}
                    // 2) an expression with method part which can host another expressions when
                    // method have parameters
                    // --> {item.getName(item.name)} --> [ObjectPart=item,
                    // MethodPart=getName(item.name))
                    // In this case, two object parts will be collected =>
                    // {|item|.getName(|item|.name)}
                    result |= tryToCollectObjectParts(partName, matcher, node, collector);
                }
                return result;
            }
        case ExpressionParts:
            {
                Parts parts = (Parts) nodeExpr;
                boolean result = false;
                for (Node partNode : parts.getChildren()) {
                    result |= tryToCollectObjectParts(partName, matcher, partNode, collector);
                }
                return result;
            }
        case ExpressionPart:
            {
                Part part = (Part) nodeExpr;
                if (part.getPartKind() == PartKind.Object) {
                    ObjectPart objectPart = (ObjectPart) part;
                    if (isMatch(objectPart, partName, matcher)) {
                        Range range = QutePositionUtility.createRange(objectPart);
                        collector.accept(objectPart, range);
                        return true;
                    }
                } else if (part.getPartKind() == PartKind.Method) {
                    MethodPart methodPart = (MethodPart) part;
                    List<Parameter> parameters = methodPart.getParameters();
                    boolean result = false;
                    for (Parameter parameter : parameters) {
                        Expression paramExpr = parameter.getJavaTypeExpression();
                        if (paramExpr != null) {
                            result |= tryToCollectObjectParts(partName, matcher, paramExpr, collector);
                        }
                    }
                    return result;
                }
            }
            break;
        default:
            break;
    }
    return false;
}
Also used : ObjectPart(com.redhat.qute.parser.expression.ObjectPart) Expression(com.redhat.qute.parser.template.Expression) Parts(com.redhat.qute.parser.expression.Parts) ObjectPart(com.redhat.qute.parser.expression.ObjectPart) NamespacePart(com.redhat.qute.parser.expression.NamespacePart) MethodPart(com.redhat.qute.parser.expression.MethodPart) Part(com.redhat.qute.parser.expression.Part) Node(com.redhat.qute.parser.template.Node) Parameter(com.redhat.qute.parser.template.Parameter) List(java.util.List) Range(org.eclipse.lsp4j.Range) MethodPart(com.redhat.qute.parser.expression.MethodPart)

Example 10 with Expression

use of com.redhat.qute.parser.template.Expression 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)

Aggregations

Expression (com.redhat.qute.parser.template.Expression)12 Node (com.redhat.qute.parser.template.Node)8 Parameter (com.redhat.qute.parser.template.Parameter)7 Range (org.eclipse.lsp4j.Range)6 Part (com.redhat.qute.parser.expression.Part)5 Section (com.redhat.qute.parser.template.Section)5 ResolvedJavaTypeInfo (com.redhat.qute.commons.ResolvedJavaTypeInfo)4 ObjectPart (com.redhat.qute.parser.expression.ObjectPart)4 List (java.util.List)4 MethodPart (com.redhat.qute.parser.expression.MethodPart)3 NamespacePart (com.redhat.qute.parser.expression.NamespacePart)3 Parts (com.redhat.qute.parser.expression.Parts)3 DiagnosticDataFactory.createDiagnostic (com.redhat.qute.services.diagnostics.DiagnosticDataFactory.createDiagnostic)3 Diagnostic (org.eclipse.lsp4j.Diagnostic)3 InvalidMethodReason (com.redhat.qute.commons.InvalidMethodReason)2 JavaMemberInfo (com.redhat.qute.commons.JavaMemberInfo)2 BadLocationException (com.redhat.qute.ls.commons.BadLocationException)2 JavaTypeInfoProvider (com.redhat.qute.parser.template.JavaTypeInfoProvider)2 LoopSection (com.redhat.qute.parser.template.sections.LoopSection)2 JavaMemberResult (com.redhat.qute.project.JavaMemberResult)2