Search in sources :

Example 1 with Parameter

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

the class QuteDiagnostics method validateMethodPart.

/**
 * Validate the given method part.
 *
 * @param part                     the method part to validate.
 * @param ownerSection             the owner section and null otherwise.
 * @param template                 the template.
 * @param projectUri               the project Uri.
 * @param resolutionContext        the resolution context.
 * @param baseType                 the base object type.
 * @param iterableOfType           the iterable of type.
 * @param diagnostics              the diagnostic list to fill.
 * @param resolvingJavaTypeContext the resolving Java type context.
 *
 * @return the Java type returned by the member part and null otherwise.
 */
private ResolvedJavaTypeInfo validateMethodPart(MethodPart methodPart, Section ownerSection, Template template, String projectUri, QuteValidationSettings validationSettings, ResolutionContext resolutionContext, ResolvedJavaTypeInfo resolvedJavaType, ResolvedJavaTypeInfo iter, List<Diagnostic> diagnostics, ResolvingJavaTypeContext resolvingJavaTypeContext) {
    // Validate parameters of the method part
    boolean undefinedType = false;
    List<ResolvedJavaTypeInfo> parameterTypes = new ArrayList<>();
    for (Parameter parameter : methodPart.getParameters()) {
        ResolvedJavaTypeInfo result = null;
        Expression expression = parameter.getJavaTypeExpression();
        if (expression != null) {
            result = validateExpression(expression, ownerSection, template, validationSettings, resolutionContext, resolvingJavaTypeContext, diagnostics);
        }
        if (result == null) {
            undefinedType = true;
        }
        parameterTypes.add(result);
    }
    if (undefinedType) {
        // One of parameter cannot be resolved as type, teh validation is stopped
        return null;
    }
    // All parameters are resolved, validate the existing of method name according
    // to the computed parameter types
    String methodName = methodPart.getPartName();
    String namespace = methodPart.getNamespace();
    JavaMemberResult result = javaCache.findMethod(resolvedJavaType, namespace, methodName, parameterTypes, projectUri);
    JavaMethodInfo method = (JavaMethodInfo) result.getMember();
    if (method == null) {
        QuteErrorCode errorCode = QuteErrorCode.UnknownMethod;
        String arg = null;
        if (namespace != null) {
            // ex :{config.getXXXX()}
            errorCode = QuteErrorCode.UnknownNamespaceResolverMethod;
            arg = namespace;
        } else {
            // ex : {@org.acme.Item item}
            // {item.getXXXX()}
            arg = resolvedJavaType.getSignature();
            InvalidMethodReason reason = javaCache.getInvalidMethodReason(methodName, resolvedJavaType, projectUri);
            if (reason != null) {
                switch(reason) {
                    case VoidReturn:
                        errorCode = QuteErrorCode.InvalidMethodVoid;
                        break;
                    case Static:
                        errorCode = QuteErrorCode.InvalidMethodStatic;
                        break;
                    case FromObject:
                        errorCode = QuteErrorCode.InvalidMethodFromObject;
                        break;
                    default:
                }
            }
        }
        Range range = QutePositionUtility.createRange(methodPart);
        Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, errorCode, methodName, arg);
        diagnostics.add(diagnostic);
        return null;
    }
    boolean matchVirtualMethod = result.isMatchVirtualMethod();
    if (!matchVirtualMethod) {
        Range range = QutePositionUtility.createRange(methodPart);
        Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, // 
        QuteErrorCode.InvalidVirtualMethod, // 
        method.getName(), // 
        method.getSimpleSourceType(), resolvedJavaType.getJavaElementSimpleType());
        diagnostics.add(diagnostic);
        return null;
    }
    boolean matchParameters = result.isMatchParameters();
    if (!matchParameters) {
        // The method codePointAt(int) in the type String is not applicable for the
        // arguments ()
        StringBuilder expectedSignature = new StringBuilder("(");
        boolean ignoreParameter = method.isVirtual();
        for (JavaParameterInfo parameter : method.getParameters()) {
            if (!ignoreParameter) {
                if (expectedSignature.length() > 1) {
                    expectedSignature.append(", ");
                }
                expectedSignature.append(parameter.getJavaElementSimpleType());
            }
            ignoreParameter = false;
        }
        expectedSignature.append(")");
        expectedSignature.insert(0, method.getName());
        StringBuilder actualSignature = new StringBuilder("(");
        for (ResolvedJavaTypeInfo parameterType : parameterTypes) {
            if (actualSignature.length() > 1) {
                actualSignature.append(", ");
            }
            actualSignature.append(parameterType != null ? parameterType.getJavaElementSimpleType() : parameterType);
        }
        actualSignature.append(")");
        Range range = QutePositionUtility.createRange(methodPart);
        Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, // 
        QuteErrorCode.InvalidMethodParameter, // 
        expectedSignature.toString(), // 
        method.getSimpleSourceType(), /* String */
        actualSignature.toString());
        diagnostics.add(diagnostic);
        return null;
    }
    String memberType = method.resolveJavaElementType(iter);
    return validateJavaTypePart(methodPart, ownerSection, projectUri, diagnostics, resolvingJavaTypeContext, memberType);
}
Also used : JavaMemberResult(com.redhat.qute.project.JavaMemberResult) ResolvedJavaTypeInfo(com.redhat.qute.commons.ResolvedJavaTypeInfo) ArrayList(java.util.ArrayList) DiagnosticDataFactory.createDiagnostic(com.redhat.qute.services.diagnostics.DiagnosticDataFactory.createDiagnostic) Diagnostic(org.eclipse.lsp4j.Diagnostic) Range(org.eclipse.lsp4j.Range) QuteErrorCode(com.redhat.qute.services.diagnostics.QuteErrorCode) JavaMethodInfo(com.redhat.qute.commons.JavaMethodInfo) Expression(com.redhat.qute.parser.template.Expression) Parameter(com.redhat.qute.parser.template.Parameter) InvalidMethodReason(com.redhat.qute.commons.InvalidMethodReason) JavaParameterInfo(com.redhat.qute.commons.JavaParameterInfo)

Example 2 with Parameter

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

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

the class WhenSection method accept0.

@Override
protected void accept0(ASTVisitor visitor) {
    boolean visitChildren = visitor.visit(this);
    if (visitChildren) {
        List<Parameter> parameters = getParameters();
        for (Parameter parameter : parameters) {
            acceptChild(visitor, parameter);
        }
        acceptChildren(visitor, getChildren());
    }
    visitor.endVisit(this);
}
Also used : Parameter(com.redhat.qute.parser.template.Parameter)

Example 4 with Parameter

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

the class QuteDiagnostics method validateIncludeSection.

/**
 * Validate #include section.
 *
 * @param includeSection the include section
 * @param diagnostics    the diagnostics to fill.
 */
private static void validateIncludeSection(IncludeSection includeSection, List<Diagnostic> diagnostics) {
    Parameter templateParameter = includeSection.getTemplateParameter();
    if (templateParameter != null) {
        // include defines a template to include
        // ex : {#include base}
        Path templateFile = includeSection.getReferencedTemplateFile();
        if (templateFile == null || Files.notExists(templateFile)) {
            // It doesn't exists a file named base, base.qute.html, base.html, etc
            Range range = QutePositionUtility.createRange(templateParameter);
            Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, QuteErrorCode.TemplateNotFound, templateParameter.getValue());
            diagnostics.add(diagnostic);
        }
    } else {
        // #include doesn't define a template id
        // ex: {#include}
        Range range = QutePositionUtility.selectStartTagName(includeSection);
        Diagnostic diagnostic = createDiagnostic(range, DiagnosticSeverity.Error, QuteErrorCode.TemplateNotDefined);
        diagnostics.add(diagnostic);
    }
}
Also used : Path(java.nio.file.Path) Parameter(com.redhat.qute.parser.template.Parameter) DiagnosticDataFactory.createDiagnostic(com.redhat.qute.services.diagnostics.DiagnosticDataFactory.createDiagnostic) Diagnostic(org.eclipse.lsp4j.Diagnostic) Range(org.eclipse.lsp4j.Range)

Example 5 with Parameter

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

Aggregations

Parameter (com.redhat.qute.parser.template.Parameter)30 Node (com.redhat.qute.parser.template.Node)9 Section (com.redhat.qute.parser.template.Section)9 Range (org.eclipse.lsp4j.Range)9 Expression (com.redhat.qute.parser.template.Expression)6 LoopSection (com.redhat.qute.parser.template.sections.LoopSection)6 ResolvedJavaTypeInfo (com.redhat.qute.commons.ResolvedJavaTypeInfo)3 NamespacePart (com.redhat.qute.parser.expression.NamespacePart)3 Part (com.redhat.qute.parser.expression.Part)3 ParameterDeclaration (com.redhat.qute.parser.template.ParameterDeclaration)3 DiagnosticDataFactory.createDiagnostic (com.redhat.qute.services.diagnostics.DiagnosticDataFactory.createDiagnostic)3 Path (java.nio.file.Path)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Diagnostic (org.eclipse.lsp4j.Diagnostic)3 BadLocationException (com.redhat.qute.ls.commons.BadLocationException)2 MethodPart (com.redhat.qute.parser.expression.MethodPart)2 RangeOffset (com.redhat.qute.parser.template.RangeOffset)2 Template (com.redhat.qute.parser.template.Template)2 IncludeSection (com.redhat.qute.parser.template.sections.IncludeSection)2