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

ktlint raise error when there is empty enum class #1711

Closed
ganadist opened this issue Nov 20, 2022 · 1 comment · Fixed by #1826
Closed

ktlint raise error when there is empty enum class #1711

ganadist opened this issue Nov 20, 2022 · 1 comment · Fixed by #1826

Comments

@ganadist
Copy link
Contributor

Expected Behavior

When kotlin project has empty enum class, ktlint raise error.

$ git clone https://github.com/ganadist/VersionCodeDemo -b ktlint_0471_error
$ cd VersionCodeDemo
$ ./gradlew :ktlint

Observed Behavior

> Task :ktlint FAILED
00:41:59.889 [main] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - Discovered reporter with "baseline" id.
00:41:59.890 [main] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - Discovered reporter with "checkstyle" id.
00:41:59.890 [main] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - Discovered reporter with "json" id.
00:41:59.890 [main] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - Discovered reporter with "format" id.
00:41:59.890 [main] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - Discovered reporter with "html" id.
00:41:59.890 [main] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - Discovered reporter with "plain" id.
00:41:59.890 [main] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - Discovered reporter with "sarif" id.
00:41:59.890 [main] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - Initializing "plain" reporter with {verbose=false, color=false, color_name=DARK_GRAY, format=false}
00:41:59.904 [main] DEBUG com.pinterest.ktlint.internal.FileUtils - Start walkFileTree for rootDir: 'VersionCodeDemo'
   include:
[      - sun.nio.fs.UnixFileSystem$3@2e4b8173]
   exclude:
[      - sun.nio.fs.UnixFileSystem$3@70e8f8e,       - sun.nio.fs.UnixFileSystem$3@17046283,       - sun.nio.fs.UnixFileSystem$3@5bd03f44,       - sun.nio.fs.UnixFileSystem$3@29626d54,       - sun.nio.fs.UnixFileSystem$3@5a63f509,       - sun.nio.fs.UnixFileSystem$3@6e4784bc,       - sun.nio.fs.UnixFileSystem$3@34b7ac2f,       - sun.nio.fs.UnixFileSystem$3@e056f20]
00:41:59.913 [main] DEBUG com.pinterest.ktlint.internal.FileUtils - Discovered 1 files to be processed in 9 ms
00:42:00.357 [pool-1-thread-1] DEBUG com.pinterest.ktlint.core.internal.RuleRunnerSorter - Rule with id 'standard:indent' should run after the rule with id 'experimental:function-signature'. However, the latter rule is not loaded and is allowed to be ignored. For best results, it is advised load the rule.
00:42:00.358 [pool-1-thread-1] DEBUG com.pinterest.ktlint.core.internal.RuleRunnerSorter - Rules will be executed in order below (unless disabled):
           - standard:annotation, 
           - standard:annotation-spacing, 
           - standard:argument-list-wrapping, 
           - standard:chain-wrapping, 
           - standard:colon-spacing, 
           - standard:comma-spacing, 
           - standard:comment-spacing, 
           - standard:curly-spacing, 
           - standard:dot-spacing, 
           - standard:double-colon-spacing, 
           - standard:enum-entry-name-case, 
           - standard:filename, 
           - standard:final-newline, 
           - standard:import-ordering, 
           - standard:keyword-spacing, 
           - standard:modifier-order, 
           - standard:multiline-if-else, 
           - standard:no-blank-line-before-rbrace, 
           - standard:no-blank-lines-in-chained-method-calls, 
           - standard:no-consecutive-blank-lines, 
           - standard:no-empty-class-body, 
           - standard:no-empty-first-line-in-method-block, 
           - standard:no-line-break-after-else, 
           - standard:no-line-break-before-assignment, 
           - standard:no-multi-spaces, 
           - standard:no-semi, 
           - standard:no-trailing-spaces, 
           - standard:no-unit-return, 
           - standard:no-unused-imports, 
           - standard:no-wildcard-imports, 
           - standard:op-spacing, 
           - standard:package-name, 
           - standard:parameter-list-wrapping, 
           - standard:paren-spacing, 
           - standard:range-spacing, 
           - standard:spacing-around-angle-brackets, 
           - standard:spacing-between-declarations-with-annotations, 
           - standard:spacing-between-declarations-with-comments, 
           - standard:string-template, 
           - standard:unary-op-spacing, 
           - standard:wrapping, 
           - standard:indent, 
           - standard:trailing-comma-on-call-site, 
           - standard:max-line-length, 
           - standard:trailing-comma-on-declaration-site
00:42:00.407 [pool-1-thread-1] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - Internal Error (trailing-comma-on-declaration-site) in file '/home/ganadist/src/build/AndroidStudioProjects/vcd/lib/hostconfig/src/main/java/com/example/myapplication/hostconfig/TestView.kt' at position '1:1
com.pinterest.ktlint.core.RuleExecutionException: com.pinterest.ktlint.core.RuleExecutionException: com.pinterest.ktlint.core.RuleExecutionException: com.pinterest.ktlint.core.RuleExecutionException: java.util.NoSuchElementException: Sequence contains no element matching the predicate.
	at com.pinterest.ktlint.core.KtLint.executeRuleOnNodeRecursively(KtLint.kt:233)
	at com.pinterest.ktlint.core.KtLint.executeRule(KtLint.kt:195)
	at com.pinterest.ktlint.core.KtLint.access$executeRule(KtLint.kt:30)
	at com.pinterest.ktlint.core.KtLint$lint$1.invoke(KtLint.kt:176)
	at com.pinterest.ktlint.core.KtLint$lint$1.invoke(KtLint.kt:175)
	at com.pinterest.ktlint.core.internal.VisitorProvider$visitor$6.invoke(VisitorProvider.kt:80)
	at com.pinterest.ktlint.core.internal.VisitorProvider$visitor$6.invoke(VisitorProvider.kt:78)
	at com.pinterest.ktlint.core.KtLint.lint(KtLint.kt:175)
	at com.pinterest.ktlint.internal.FileUtilsKt.lintFile(FileUtils.kt:363)
	at com.pinterest.ktlint.internal.KtlintCommandLine.process(KtlintCommandLine.kt:410)
	at com.pinterest.ktlint.internal.KtlintCommandLine.access$process(KtlintCommandLine.kt:52)
	at com.pinterest.ktlint.internal.KtlintCommandLine$lintFiles$3.invoke$lambda-0(KtlintCommandLine.kt:313)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.pinterest.ktlint.core.RuleExecutionException: com.pinterest.ktlint.core.RuleExecutionException: com.pinterest.ktlint.core.RuleExecutionException: java.util.NoSuchElementException: Sequence contains no element matching the predicate.
	at com.pinterest.ktlint.core.KtLint.executeRuleOnNodeRecursively(KtLint.kt:233)
	at com.pinterest.ktlint.core.KtLint.executeRuleOnNodeRecursively(KtLint.kt:219)
	... 15 common frames omitted
Caused by: com.pinterest.ktlint.core.RuleExecutionException: com.pinterest.ktlint.core.RuleExecutionException: java.util.NoSuchElementException: Sequence contains no element matching the predicate.
	at com.pinterest.ktlint.core.KtLint.executeRuleOnNodeRecursively(KtLint.kt:233)
	at com.pinterest.ktlint.core.KtLint.executeRuleOnNodeRecursively(KtLint.kt:219)
	... 16 common frames omitted
Caused by: com.pinterest.ktlint.core.RuleExecutionException: java.util.NoSuchElementException: Sequence contains no element matching the predicate.
	at com.pinterest.ktlint.core.KtLint.executeRuleOnNodeRecursively(KtLint.kt:233)
	at com.pinterest.ktlint.core.KtLint.executeRuleOnNodeRecursively(KtLint.kt:219)
	... 17 common frames omitted
Caused by: java.util.NoSuchElementException: Sequence contains no element matching the predicate.
	at com.pinterest.ktlint.ruleset.standard.TrailingCommaOnDeclarationSiteRule.findNodeAfterTrailingCommaPosition(TrailingCommaOnDeclarationSiteRule.kt:505)
	at com.pinterest.ktlint.ruleset.standard.TrailingCommaOnDeclarationSiteRule.visitClass(TrailingCommaOnDeclarationSiteRule.kt:205)
	at com.pinterest.ktlint.ruleset.standard.TrailingCommaOnDeclarationSiteRule.beforeVisitChildNodes(TrailingCommaOnDeclarationSiteRule.kt:88)
	at com.pinterest.ktlint.core.KtLint.executeRuleOnNodeRecursively(KtLint.kt:209)
	... 18 common frames omitted
VersionCodeDemo/lib/hostconfig/src/main/java/com/example/myapplication/hostconfig/TestView.kt:1:1: Internal Error (trailing-comma-on-declaration-site) in file 'VersionCodeDemo/lib/hostconfig/src/main/java/com/example/myapplication/hostconfig/TestView.kt' at position '1:1. Please create a ticket at https://github.com/pinterest/ktlint/issues (if possible, please re-run with the --debug flag to get the stacktrace and provide the source code that triggered an error) (cannot be auto-corrected) ()
00:42:00.409 [main] DEBUG com.pinterest.ktlint.internal.KtlintCommandLine - 555ms / 1 file(s) / 1 error(s)

Steps to Reproduce

Your Environment

@paul-dingemans paul-dingemans added this to the 0.49.0 milestone Nov 20, 2022
@paul-dingemans
Copy link
Collaborator

Tnx for reporting. It seems a rare edge case to me. I will skip it for the upcoming release (0.48) and fix it later.

paul-dingemans added a commit that referenced this issue Feb 18, 2023
paul-dingemans added a commit that referenced this issue Feb 18, 2023
paul-dingemans added a commit that referenced this issue Mar 4, 2023
= Typealias EditorConfigProperties

The typealias EditorConfigProperties was not used consistently in the KtLint code base. Some methods used the underlying data type Map<String, Property> instead. The EditorConfig enforces a consistent usage as it fully encapsulates the Map<String, Property> data type. Also, the EditorConfig has a secondary constructor with a vararg arguments which results in better readable code.

The interface UsesEditorConfigProperties which optionally could be implemented on a Rule class is replaced with a property in the Rule class. If a rule wants to read a property from the EditorConfig, the property has to be registered in the field usesEditorConfigProperties of the Rule class. The RuleExecution context which provides the EditorConfig in the call to the beforeFirstNode function of the Rule instance only provides the properties that are registered in the field usesEditorConfigProperties.

The "end_of_line" property has been transformed to an official EditorConfigProperty END_OF_LINE_PROPERTY and has been added to the default editor config properties. The value "native" has been dropped as this value is not recognized by the ec4j library nor IntelliJ IDEA.

The EditorConfigGenerator has been simplified as the EditConfig can not contain multiple properties with the same name but having different Property definitions.

Fixed a problem in FORCE_MULTILINE_WHEN_PARAMETER_COUNT_GREATER_OR_EQUAL_THAN_PROPERTY the old default value -1 is not accepted as it is not a positive integer.

Fixed a problem in the EditorConfigLoader when ignoreEditorConfigOnFileSystem is enabled. The editorConfigDefaults will only be taken into account whenever the ec4j library is queried to retrieve the editor config for an extension at an existing path. This flag is supposed to be enabled while running unit tests which should not be affected by a '.editorconfig' file which exists on the filesystem where the tests are executed. For now, it is assumed that the file system does not contain such file in the root of the file system.

Create extension function to transform an EditorConfigProperty to an ec4j Property with a value.

Do not throw exception when enum class does not contain entries.
Closes #1711

= Avoid class cast exceptions when retrieving a property without (ec4j) type
Both the rules provided by Ktlint and custom rules can define properties with property types that are unknown to ec4j. If such custom property types are not provided to the ec4j library when reading the ".editorconfig" file this results in a property with a null type. Parsing a value of such a property always results in a value of type String which might not corresponding with the real type of the property.

Another problem is that ec4j expects the name of a property to be identical to the name of the corresponding PropertyType. When no propertyType is found with a name identical to the name of the property, the type of the property becomes null.

When building a property using the "Property.Builder" of ec4j, it is not possible to create a property having a null type. But when loading an ".editorconfig" file containing a custom property for which the propertyType was not registered in the EditorConfigLoader of ec4j does result in such a property.
Closes #1806

Problems above are mitigated as follows:

Wrap the ec4j EditorConfigLoader into EditorConfigLoaderEc4j and ensure that only the latter class is calling the ec4j EditorConfigLoader.
Enforce that the EditorConfigDefaults can only be loaded when the propertyTypes have been given.
When retrieving a value for an EditorConfigProperty from EditorConfig then always ignore the type of the ec4j property but use the type of the EditorConfigProperty itself.
Add KtlintTestFileSystem as test utility whenever testing with ".editorconfig" files. Refactor all tests doing so.

= Replace KtLintRuleEngine parameter "ignoreEditorConfigOnFileSystem" with "fileSystem"

This property is primarily intended to be used in unit tests. By specifying an alternative FileSystem the unit test gains control on whether the EditorConfigLoader should or should not read specific ".editorconfig" files. For example, it is considered unwanted that a unit test is influenced by the ".editorconfig" file of the project in which the unit test is included.

= Do not expose rule runners from RuleExecutionContext in case the rule is disabled.
After loading the EditorConfig it can be determined which rules are enabled or disabled. The "EditorConfig.get(EditorConfigProperty)" function can not be used for this as this would require such properties to be created dynamically. As those properties are required only to decide which rules are executed, it does not make sense to store them in the EditorConfig that is used for propagation of properties to the rules.

The logic which determine whether a rule is enabled or disabled is moved to RuleFilters. The RuleExecutionRuleFilter contains the logic extracted from the VisitorProvider. Likewise the RunAfterRuleFilter contains the logic which is extracted from the the RuleRunnerSorter. The RuleFilters are applied by the RuleExecutionContext before exposing them to the VisitorProvider. As of that the VisitorProvider now receives a set of RuleRunners that are enabled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants