Skip to content

fix: ensure Dockerfile analysis works in IntelliJ 2026.1 with bundled TextMate Docker grammar#249

Merged
soul2zimate merged 3 commits into
redhat-developer:mainfrom
soul2zimate:TC-3906
Mar 27, 2026
Merged

fix: ensure Dockerfile analysis works in IntelliJ 2026.1 with bundled TextMate Docker grammar#249
soul2zimate merged 3 commits into
redhat-developer:mainfrom
soul2zimate:TC-3906

Conversation

@soul2zimate

Copy link
Copy Markdown
Contributor

soul2zimate and others added 2 commits March 27, 2026 15:31
The parser was failing on common Dockerfile constructs:
- Missing instructions: MAINTAINER, HEALTHCHECK, SHELL, STOPSIGNAL, ONBUILD
- Line continuations with trailing whitespace after backslash
- Comments inside multi-line instructions breaking continuation
- ARG values containing paths (e.g., ARG HOME=/app)
- Heredoc syntax (<<EOF...EOF) causing parse errors
- Single-digit image tags (e.g., FROM rust:1) misidentified by lexer

Add unknownLine catch-all rule so unrecognized content is silently
skipped instead of causing parse errors. Reorder lexer rules so
ANY_CHAR (single-char catch-all) doesn't shadow VERSION, IDENTIFIER,
and IMAGE_NAME_TOKEN on same-length matches.

Tested against 85+ real-world Dockerfiles across multiple frameworks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… TextMate Docker grammar

IntelliJ 2026.1 bundles a TextMate Docker grammar that claims Dockerfile
files with TextMateFileType, which implements PlainTextLikeFileType.
This marker interface causes IntelliJ's DaemonCodeAnalyzer to skip
ExternalAnnotator execution, preventing vulnerability analysis.

Add FileTypeOverrider to force Dockerfiles to use our rhda-dockerfile
file type and parser, ensuring the annotator and inspection fire correctly.
Also add isDockerfile() utility for filename-based detection supporting
Dockerfile, Containerfile, and their variants.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Fix Dockerfile parser for real-world syntax and IntelliJ 2026.1 compatibility

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Improve Dockerfile parser to handle real-world syntax constructs
  - Add support for missing instructions: MAINTAINER, HEALTHCHECK, SHELL, STOPSIGNAL, ONBUILD
  - Fix line continuations with trailing whitespace after backslash
  - Handle comments inside multi-line instructions without breaking continuation
  - Support ARG values containing paths and heredoc syntax
  - Fix single-digit image tags misidentified by lexer
• Ensure Dockerfile analysis works in IntelliJ 2026.1 with bundled TextMate Docker grammar
  - Add FileTypeOverrider to force Dockerfiles to use custom rhda-dockerfile file type
  - Add isDockerfile() utility for filename-based detection supporting Dockerfile, Containerfile
  variants
• Add comprehensive parser tests covering 85+ real-world Dockerfile patterns
Diagram
flowchart LR
  A["Dockerfile Lexer<br/>dockerfile.flex"] -->|Add LINE_CONTINUATION<br/>Reorder lexer rules| B["DockerfileLexer.java<br/>Generated"]
  A -->|Add missing keywords| C["DockerfileTypes.java<br/>Token types"]
  D["Dockerfile Grammar<br/>dockerfile.bnf"] -->|Add unknownLine rule<br/>Add new instructions| E["DockerfileParser.java<br/>Generated"]
  D -->|Update argValue<br/>instructionArgs| F["Parser Rules"]
  G["DockerfileFileType.java"] -->|Add isDockerfile utility| H["File Detection"]
  I["DockerfileFileTypeOverrider.java<br/>New"] -->|Override TextMate<br/>file type| J["IntelliJ 2026.1<br/>Compatibility"]
  K["DockerfileAnnotator.java"] -->|Use isDockerfile| L["Vulnerability Analysis"]
  M["Test Resources<br/>9 Dockerfiles"] -->|Validate parser| N["DockerfileParserTest.java<br/>258 test cases"]
Loading

Grey Divider

File Changes

1. src/main/java/org/jboss/tools/intellij/image/build/dockerfile.flex ✨ Enhancement +16/-4

Add missing instructions and fix line continuation handling

src/main/java/org/jboss/tools/intellij/image/build/dockerfile.flex


2. src/main/gen/org/jboss/tools/intellij/image/build/lexer/DockerfileLexer.java Code generation +251/-177

Regenerated lexer with improved token handling

src/main/gen/org/jboss/tools/intellij/image/build/lexer/DockerfileLexer.java


3. src/main/java/org/jboss/tools/intellij/image/build/dockerfile.bnf ✨ Enhancement +11/-4

Add missing instructions and unknownLine catch-all rule

src/main/java/org/jboss/tools/intellij/image/build/dockerfile.bnf


View more (24)
4. src/main/gen/org/jboss/tools/intellij/image/build/parser/DockerfileParser.java Code generation +29/-5

Regenerated parser with new grammar rules

src/main/gen/org/jboss/tools/intellij/image/build/parser/DockerfileParser.java


5. src/main/gen/org/jboss/tools/intellij/image/build/psi/DockerfileTypes.java Code generation +5/-0

Add token types for new Dockerfile instructions

src/main/gen/org/jboss/tools/intellij/image/build/psi/DockerfileTypes.java


6. src/main/gen/org/jboss/tools/intellij/image/build/psi/DockerfileArgValue.java Code generation +3/-0

Add IMAGE_NAME_TOKEN getter to PSI interface

src/main/gen/org/jboss/tools/intellij/image/build/psi/DockerfileArgValue.java


7. src/main/gen/org/jboss/tools/intellij/image/build/psi/DockerfileInstructionArgs.java Code generation +3/-0

Add COMMENT getter to PSI interface

src/main/gen/org/jboss/tools/intellij/image/build/psi/DockerfileInstructionArgs.java


8. src/main/gen/org/jboss/tools/intellij/image/build/psi/impl/DockerfileArgValueImpl.java Code generation +6/-0

Implement getImageNameToken method

src/main/gen/org/jboss/tools/intellij/image/build/psi/impl/DockerfileArgValueImpl.java


9. src/main/gen/org/jboss/tools/intellij/image/build/psi/impl/DockerfileInstructionArgsImpl.java Code generation +6/-0

Implement getComment method

src/main/gen/org/jboss/tools/intellij/image/build/psi/impl/DockerfileInstructionArgsImpl.java


10. src/main/java/org/jboss/tools/intellij/image/build/filetype/DockerfileFileType.java ✨ Enhancement +22/-0

Add isDockerfile utility methods for filename detection

src/main/java/org/jboss/tools/intellij/image/build/filetype/DockerfileFileType.java


11. src/main/java/org/jboss/tools/intellij/image/build/filetype/DockerfileFileTypeOverrider.java 🐞 Bug fix +38/-0

New file type override to prevent TextMate grammar interference

src/main/java/org/jboss/tools/intellij/image/build/filetype/DockerfileFileTypeOverrider.java


12. src/main/java/org/jboss/tools/intellij/image/DockerfileAnnotator.java 🐞 Bug fix +2/-2

Use isDockerfile utility for file type checking

src/main/java/org/jboss/tools/intellij/image/DockerfileAnnotator.java


13. src/main/java/org/jboss/tools/intellij/image/ImageReportAction.java 🐞 Bug fix +1/-1

Use isDockerfile utility for file type checking

src/main/java/org/jboss/tools/intellij/image/ImageReportAction.java


14. src/main/java/org/jboss/tools/intellij/image/ImageReportIntentionAction.java 🐞 Bug fix +1/-1

Use isDockerfile utility for file type checking

src/main/java/org/jboss/tools/intellij/image/ImageReportIntentionAction.java


15. src/main/java/org/jboss/tools/intellij/image/ImageService.java 🐞 Bug fix +1/-1

Use isDockerfile utility for file type checking

src/main/java/org/jboss/tools/intellij/image/ImageService.java


16. src/main/java/org/jboss/tools/intellij/image/UBIIntentionAction.java 🐞 Bug fix +1/-1

Use isDockerfile utility for file type checking

src/main/java/org/jboss/tools/intellij/image/UBIIntentionAction.java


17. src/main/resources/META-INF/plugin.xml ⚙️ Configuration changes +5/-0

Register FileTypeOverrider for Dockerfile file type detection

src/main/resources/META-INF/plugin.xml


18. src/test/java/org/jboss/tools/intellij/image/DockerfileParserTest.java 🧪 Tests +258/-0

Add comprehensive parser tests for real-world Dockerfiles

src/test/java/org/jboss/tools/intellij/image/DockerfileParserTest.java


19. src/test/resources/dockerfiles/all-instructions.Dockerfile 🧪 Tests +18/-0

Test resource with all Dockerfile instructions

src/test/resources/dockerfiles/all-instructions.Dockerfile


20. src/test/resources/dockerfiles/arg-with-path.Dockerfile 🧪 Tests +48/-0

Test resource for ARG with path values

src/test/resources/dockerfiles/arg-with-path.Dockerfile


21. src/test/resources/dockerfiles/comments-in-continuation.Dockerfile 🧪 Tests +34/-0

Test resource for comments in multi-line instructions

src/test/resources/dockerfiles/comments-in-continuation.Dockerfile


22. src/test/resources/dockerfiles/heredoc-syntax.Dockerfile 🧪 Tests +28/-0

Test resource for heredoc syntax support

src/test/resources/dockerfiles/heredoc-syntax.Dockerfile


23. src/test/resources/dockerfiles/maintainer-and-multiline.Dockerfile 🧪 Tests +14/-0

Test resource for MAINTAINER and line continuations

src/test/resources/dockerfiles/maintainer-and-multiline.Dockerfile


24. src/test/resources/dockerfiles/multistage-with-args.Dockerfile 🧪 Tests +4/-0

Test resource for multi-stage builds with ARG

src/test/resources/dockerfiles/multistage-with-args.Dockerfile


25. src/test/resources/dockerfiles/shell-subcommands.Dockerfile 🧪 Tests +20/-0

Test resource for shell subcommands in RUN

src/test/resources/dockerfiles/shell-subcommands.Dockerfile


26. src/test/resources/dockerfiles/simple-with-tag.Dockerfile 🧪 Tests +20/-0

Test resource for simple Dockerfile with single-digit tags

src/test/resources/dockerfiles/simple-with-tag.Dockerfile


27. src/test/resources/dockerfiles/unicode-comments.Dockerfile 🧪 Tests +20/-0

Test resource for unicode characters in comments

src/test/resources/dockerfiles/unicode-comments.Dockerfile


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Mar 27, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 📐 Spec deviations (0)

Grey Divider


Remediation recommended

1. Annotator gated by filename 🐞 Bug ✓ Correctness
Description
DockerfileAnnotator.collectInformation now returns null unless DockerfileFileType.isDockerfile(file)
matches filename heuristics, which can skip vulnerability analysis for files already using the
rhda-dockerfile file type but named differently (e.g., user file-type association). This is a
behavioral regression compared to checking file.getFileType() and can silently disable analysis.
Code

src/main/java/org/jboss/tools/intellij/image/DockerfileAnnotator.java[R259-262]

+        // Only process Dockerfile files
+        if (!DockerfileFileType.isDockerfile(file)) {
            return null;
        }
Evidence
The annotator now exits early based on DockerfileFileType.isDockerfile(PsiFile), which only checks
VirtualFile/name patterns and does not consider that a PsiFile can already be of
DockerfileFileType.INSTANCE via explicit association. Dockerfile PSI files report
DockerfileFileType.INSTANCE regardless of filename, so filename-only gating can block analysis even
when the IDE has assigned the correct file type/language.

src/main/java/org/jboss/tools/intellij/image/DockerfileAnnotator.java[257-262]
src/main/java/org/jboss/tools/intellij/image/build/filetype/DockerfileFileType.java[26-44]
src/main/java/org/jboss/tools/intellij/image/build/psi/DockerfileFile.java[21-30]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`DockerfileAnnotator.collectInformation()` is currently gated by `DockerfileFileType.isDockerfile(file)`, which only checks filename patterns. This can skip analysis for files that IntelliJ has already assigned to `DockerfileFileType.INSTANCE` (e.g., via explicit user association) but whose names don’t match the hard-coded patterns.

### Issue Context
External annotator registration is language-based (`rhda-dockerfile`), so if a file is already of this language/file type, it should not be excluded purely due to its filename.

### Fix Focus Areas
- src/main/java/org/jboss/tools/intellij/image/DockerfileAnnotator.java[257-262]
- src/main/java/org/jboss/tools/intellij/image/build/filetype/DockerfileFileType.java[26-44]

### Suggested fix
Update `DockerfileFileType.isDockerfile(PsiFile)` (or the annotator check) to return true when `file.getFileType() == DockerfileFileType.INSTANCE` (and only fall back to filename heuristics otherwise). Apply the same approach for callers that currently switched from file-type checks to name-only checks if they should respect explicit file-type association.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

2. Internal API filetype override 🐞 Bug ⚙ Maintainability
Description
DockerfileFileTypeOverrider depends on com.intellij.openapi.fileTypes.impl.FileTypeOverrider (an
internal API), increasing the risk of breakage across IDE versions. If this API changes or is
unavailable in some IDE distributions, the plugin can fail to load or the override may stop working,
re-breaking Dockerfile analysis.
Code

src/main/java/org/jboss/tools/intellij/image/build/filetype/DockerfileFileTypeOverrider.java[R14-35]

+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.impl.FileTypeOverrider;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Overrides the file type for Dockerfile files to ensure they use our custom
+ * rhda-dockerfile language and parser, even when IntelliJ's bundled TextMate
+ * Docker bundle would otherwise claim them.
+ *
+ * This is necessary because the TextMate file type implements PlainTextLikeFileType,
+ * which causes IntelliJ to skip ExternalAnnotator execution, preventing
+ * vulnerability analysis from running.
+ */
+public class DockerfileFileTypeOverrider implements FileTypeOverrider {
+
+    @Override
+    public @Nullable FileType getOverriddenFileType(@NotNull VirtualFile file) {
+        if (DockerfileFileType.isDockerfile(file)) {
+            return DockerfileFileType.INSTANCE;
+        }
Evidence
The new overrider explicitly imports an impl-package IntelliJ class and is registered globally via
plugin.xml. This creates an ongoing compatibility/maintenance risk because impl packages are not
stable API surface.

src/main/java/org/jboss/tools/intellij/image/build/filetype/DockerfileFileTypeOverrider.java[14-37]
src/main/resources/META-INF/plugin.xml[557-567]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`DockerfileFileTypeOverrider` uses an IntelliJ internal API (`com.intellij.openapi.fileTypes.impl.FileTypeOverrider`). Internal APIs can change without notice, risking runtime failures or the override silently not working on some IDE builds.

### Issue Context
This overrider is core to ensuring Dockerfiles use `rhda-dockerfile` and thus enabling `ExternalAnnotator` execution.

### Fix Focus Areas
- src/main/java/org/jboss/tools/intellij/image/build/filetype/DockerfileFileTypeOverrider.java[14-37]
- src/main/resources/META-INF/plugin.xml[557-567]

### Suggested fix
If there is a public/stable alternative extension point/API available in the target IDE range, prefer it. Otherwise:
- add an explicit comment and/or build-range documentation for the IntelliJ versions where this is supported
- consider a defensive loading strategy (separate module, reflection, or optional registration) so the plugin degrades gracefully if the class/EP is missing.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
13 Security Hotspots

See analysis details on SonarQube Cloud

@soul2zimate
soul2zimate merged commit 529d7f2 into redhat-developer:main Mar 27, 2026
5 of 7 checks passed
@soul2zimate
soul2zimate deleted the TC-3906 branch March 27, 2026 09:06
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 this pull request may close these issues.

Docker scanning cannot be invoked in latest IntelliJ

1 participant