redhat-developer / quarkus-ls

Language server for Quarkus tooling
Eclipse Public License 2.0
43 stars 15 forks source link

CodeAction to insert expected input for renarde #form #778

Closed angelozerr closed 1 year ago

angelozerr commented 1 year ago

Given the manualLogin method of renarde controller:

public class Login extends ControllerWithUser<User> {

    @POST
    public Response manualLogin(@NotBlank @RestForm String userName,
            @RestForm String password,
            @BeanParam WebAuthnLoginResponse webAuthnResponse,
            RoutingContext ctx) 
...
}

According @NotBlank @RestForm annotations:

Given this #form in qute template:

{#form uri:Login.manualLogin() id="login"}

{/form}

We should have a warning on #form location which says that some input should be defined inside the #form. After that we can bind code action of this warning:

Click on Insert required input forms code action will insert in:

{#input name="userName" /}

Click on Insert all inputinput forms code action will insert in:

{#input name="userName" /} {#input name="password" /}

@FroMage I noticed that in your sample renarde application you are using simple HTML input element (<input name=""), I wonder if it is better to use #input ?

In your parser we can get those Qute #input user tag, but we don't parse HTML content (it is a text node for us). If you think it is very important to take care of <input HTML element, it will require for our parser to have the capability to parse HTML.

FroMage commented 1 year ago

Well, the #input tag is not part of Renarde but the TODO app, because it's very tied to the CSS framework in use, which depends on the application. So, probably better to generate <input name="xx"> tags, which are universal.

angelozerr commented 1 year ago

Thanks @FroMage for your feedback. We need to implement à basic parser to collect input html element inside #form

angelozerr commented 1 year ago

@JessicaJHee here some directive to implement this issue. In the qute diagnostic, you need to check if section is #form. In this case you need to get the first parameter of the #form (ex : uri:Login.manualLogin()) and get the RestForm of manualLogin method JavaMethodInfo.

You will need to loop for https://github.com/redhat-developer/quarkus-ls/blob/5a1b1cfc69232cab7e7198422f6e42ae6ace806b/qute.ls/com.redhat.qute.ls/src/main/java/com/redhat/qute/commons/JavaMethodInfo.java#L110 and check if RestParam is a form. At this step you can collect all required RestForm.

To check that required restParam are defined in #form as <input html element, you will need to parse HTML which is not done today but only for #form section. Perhaps it could be interesting to create a FormSection class which extends Section.

FormSection could have a method like getHtmlInputNames() which will return all input/ @name declared inside #form. To implement that, I suggest that you implement a vistor like https://github.com/redhat-developer/quarkus-ls/blob/master/qute.ls/com.redhat.qute.ls/src/main/java/com/redhat/qute/services/inlayhint/InlayHintASTVistor.java and implement visit(Text).

At this step you will have text node. You will need to parse this content to collect name of <input name="". To be consistent will all parsing, I suggest that you implement a little scanner like our parameter scanner https://github.com/redhat-developer/quarkus-ls/blob/master/qute.ls/com.redhat.qute.ls/src/main/java/com/redhat/qute/parser/parameter/scanner/ParameterScanner.java