Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sealed classes - error: expected token: 'sealed'; generated class instead #603

Closed
ZacSweers opened this issue May 2, 2021 · 1 comment
Closed

Comments

@ZacSweers
Copy link

When trying to use GJF with JDK 16, I get the following error

Caused by: com.google.googlejavaformat.java.FormatterException: 8:52: error: expected token: 'sealed'; generated class instead
        at com.google.googlejavaformat.java.Formatter.getFormatReplacements(Formatter.java:293)
        at com.google.googlejavaformat.java.Formatter.formatSource(Formatter.java:267)
        at com.google.googlejavaformat.java.Formatter.formatSource(Formatter.java:233)
        ... 135 more

With this source code

package dev.zacsweers.moshix.sealed.sample.java;

import com.squareup.moshi.JsonClass;

import dev.zacsweers.moshix.sealed.annotations.TypeLabel;

public interface FailureTestCases {
  @JsonClass(generateAdapter = false, generator = "sealed:type")
  sealed class DuplicateLabels permits DuplicateLabels.TypeA, DuplicateLabels.TypeB {
    @TypeLabel(label = "a")
    static final class TypeA extends DuplicateLabels {}

    @TypeLabel(label = "a")
    static final class TypeB extends DuplicateLabels {}
  }

  @JsonClass(generateAdapter = false, generator = "sealed:type")
  sealed class DuplicateAlternateLabels permits DuplicateAlternateLabels.TypeA, DuplicateAlternateLabels.TypeB {
    @TypeLabel(label = "a", alternateLabels = {"aa"})
    static final class TypeA extends DuplicateAlternateLabels {}

    @TypeLabel(label = "b", alternateLabels = {"aa"})
    static final class TypeB extends DuplicateAlternateLabels {}
  }

  @JsonClass(generateAdapter = false, generator = "sealed:type")
  sealed class GenericSubtypes<T> permits GenericSubtypes.TypeA, GenericSubtypes.TypeB {
    // This form is ok
    @TypeLabel(label = "a", alternateLabels = {"aa"})
    static final class TypeA extends GenericSubtypes<String> {}

    // This form is not ok
    @TypeLabel(label = "b", alternateLabels = {"aa"})
    static final class TypeB<T> extends GenericSubtypes<T> {}
  }
}

I know sealed classes are still in preview though, so understand if this isn't expected to be supported yet. The error message is a little surprising though

@kevinb9n
Copy link
Contributor

We'd like to support preview features -- if not by formatting them well, that at least through the magic of not crashing.

If for some reason this is a nontrivial fix (?), we might at least fix the error message first.

now pushed a commit to now/google-java-format that referenced this issue Jul 23, 2021
This implements support for JEP 409: Sealed Classes, see
https://openjdk.java.net/jeps/409.

The implementation handles the sealed and non-sealed keywords and sorts them
according to their JLS order.  This requires us to look at the actual text of
the Tok, as there’s no TokenKind for sealed and non-sealed.

The optional permits clause is handled in the same manner as the implements
clause. A new private method, classDeclarationTypeList, has been added to
facilitate this.

This fixes google#603.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants