redhat-developer / quarkus-ls

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

ClassCastException in qute template #816

Closed fbricon closed 1 year ago

fbricon commented 1 year ago

In a qute template, the following will trigger a ClassCastException:

    {#if !}

    {/if}

See:

[Trace - 18:50:59] Sending request 'textDocument/codeAction - (2217)'.
Mar 15, 2023 6:50:59 PM org.eclipse.lsp4j.jsonrpc.RemoteEndpoint fallbackResponseError
SEVERE: Internal error: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
java.util.concurrent.CompletionException: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
    at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture.completeThrowable(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture$Completion.exec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
Caused by: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
    at com.redhat.qute.services.codeactions.QuteCodeActionForUndefinedObject.doCodeActions(QuteCodeActionForUndefinedObject.java:77)
    at com.redhat.qute.services.QuteCodeActions.doCodeActions(QuteCodeActions.java:116)
    at com.redhat.qute.services.QuteLanguageService.doCodeActions(QuteLanguageService.java:104)
    at com.redhat.qute.ls.template.TemplateFileTextDocumentService.lambda$codeAction$9(TemplateFileTextDocumentService.java:165)
    at com.redhat.qute.ls.commons.ModelTextDocuments.lambda$computeModelAsyncCompose$1(ModelTextDocuments.java:144)
    ... 7 more

[Trace - 18:50:59] Received response 'textDocument/codeAction - (2217)' in 1ms. Request failed: Internal error. (-32603).
[Error - 18:50:59] Request textDocument/codeAction failed.
  Message: Internal error.
  Code: -32603 
java.util.concurrent.CompletionException: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
    at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture.completeThrowable(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture$Completion.exec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
Caused by: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
    at com.redhat.qute.services.codeactions.QuteCodeActionForUndefinedObject.doCodeActions(QuteCodeActionForUndefinedObject.java:77)
    at com.redhat.qute.services.QuteCodeActions.doCodeActions(QuteCodeActions.java:116)
    at com.redhat.qute.services.QuteLanguageService.doCodeActions(QuteLanguageService.java:104)
    at com.redhat.qute.ls.template.TemplateFileTextDocumentService.lambda$codeAction$9(TemplateFileTextDocumentService.java:165)
    at com.redhat.qute.ls.commons.ModelTextDocuments.lambda$computeModelAsyncCompose$1(ModelTextDocuments.java:144)
    ... 7 more

[Trace - 18:50:59] Sending notification 'textDocument/didSave'.
[Trace - 18:51:00] Sending notification 'workspace/didChangeWatchedFiles'.
[Trace - 18:51:00] Received notification 'textDocument/publishDiagnostics'.
[Trace - 18:51:00] Sending request 'textDocument/codeAction - (2218)'.
Mar 15, 2023 6:51:00 PM org.eclipse.lsp4j.jsonrpc.RemoteEndpoint fallbackResponseError
SEVERE: Internal error: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
java.util.concurrent.CompletionException: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
    at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture.completeThrowable(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture$Completion.exec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
Caused by: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
    at com.redhat.qute.services.codeactions.QuteCodeActionForUndefinedObject.doCodeActions(QuteCodeActionForUndefinedObject.java:77)
    at com.redhat.qute.services.QuteCodeActions.doCodeActions(QuteCodeActions.java:116)
    at com.redhat.qute.services.QuteLanguageService.doCodeActions(QuteLanguageService.java:104)
    at com.redhat.qute.ls.template.TemplateFileTextDocumentService.lambda$codeAction$9(TemplateFileTextDocumentService.java:165)
    at com.redhat.qute.ls.commons.ModelTextDocuments.lambda$computeModelAsyncCompose$1(ModelTextDocuments.java:144)
    ... 7 more

[Trace - 18:51:00] Received response 'textDocument/codeAction - (2218)' in 2ms. Request failed: Internal error. (-32603).
[Error - 18:51:00] Request textDocument/codeAction failed.
  Message: Internal error.
  Code: -32603 
java.util.concurrent.CompletionException: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
    at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture.completeThrowable(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(Unknown Source)
    at java.base/java.util.concurrent.CompletableFuture$Completion.exec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
Caused by: java.lang.ClassCastException: class com.redhat.qute.parser.expression.Parts cannot be cast to class com.redhat.qute.parser.expression.ObjectPart (com.redhat.qute.parser.expression.Parts and com.redhat.qute.parser.expression.ObjectPart are in unnamed module of loader 'app')
    at com.redhat.qute.services.codeactions.QuteCodeActionForUndefinedObject.doCodeActions(QuteCodeActionForUndefinedObject.java:77)
    at com.redhat.qute.services.QuteCodeActions.doCodeActions(QuteCodeActions.java:116)
    at com.redhat.qute.services.QuteLanguageService.doCodeActions(QuteLanguageService.java:104)
    at com.redhat.qute.ls.template.TemplateFileTextDocumentService.lambda$codeAction$9(TemplateFileTextDocumentService.java:165)
    at com.redhat.qute.ls.commons.ModelTextDocuments.lambda$computeModelAsyncCompose$1(ModelTextDocuments.java:144)
    ... 7 more

Tested with the latest vscode-quarkus pre-release (v1.13.2023031404)

rgrunber commented 1 year ago

@datho7561 , could we solve this by adding something like literalJavaType != null || object.getPartName().isEmpty() at https://github.com/redhat-developer/quarkus-ls/blob/c0fc3388a170e0f709df88a625ec85d3c89460cd/qute.ls/com.redhat.qute.ls/src/main/java/com/redhat/qute/services/QuteDiagnostics.java#L710-L714 ?

It doesn't make sense to emit UndefinedObject when we can't define it because it isn't a valid identifier.

angelozerr commented 1 year ago

It doesn't make sense to emit UndefinedObject when we can't define it because it isn't a valid identifier.

@rgrunber indeed it was the idea, but ! can be used as object part if it is not an #if section.

Here the result:

image

Here we don't report error as UndefinedObject. Please note that the error should highlight the ! and note the {, but this error comes from the real Qute parser which is not fault tolerant, so it means if you write:

{#if !}

    {/if}
{#if !}

    {/if}

you will have just one error of the first { and teh offset is not correct.

To fix those 2 problems we should manage this error with our QuteDiagnostics which uses our fault tolerant parser. I had started to manage an error to adjust correctly the error (I ignore the error from the Qute real parser and I manage itin QuteDiagnostics), but I'm waiting for the decision about the Qute parser (managed with Antlr?)

//cc @mkouba @JessicaJHee @datho7561