Skip to content

Netbeans cannot delete some text when editing TOML files #8174

Closed

Description

@niabot

Apache NetBeans version

Apache NetBeans 24

What happened

When editing TOML files for Gradle projects the editor hangs if there is a temporary syntax error in the files. At first the editor won't let me type anything within unmatched curly braces. Deleting the braces is also not possible. Under some circumstances the entire editor (and netbeans) hangs (endless loop). I get the following or similar exceptions:

java.lang.IllegalStateException: Lexer org.netbeans.modules.languages.toml.TomlLexer@4eeb0fe6
  returned null token but lexerInput.readLength()=2
  lexer-state: -1
  tokenStartOffset=1778, readOffset=1780, lookaheadOffset=1781
  Chars: "\n\n" - these characters need to be tokenized.
Fix the lexer to not return null token in this state.
	at org.netbeans.lib.lexer.LexerInputOperation.checkLexerInputFinished(LexerInputOperation.java:435)
	at org.netbeans.lib.lexer.LexerInputOperation.nextToken(LexerInputOperation.java:193)
	at org.netbeans.lib.lexer.inc.IncTokenList.tokenOrEmbeddingImpl(IncTokenList.java:170)
	at org.netbeans.lib.lexer.inc.IncTokenList.tokenOrEmbedding(IncTokenList.java:165)
	at org.netbeans.api.lexer.TokenSequence.moveNext(TokenSequence.java:458)
	at org.netbeans.modules.textmate.lexer.SyntaxHighlighting$TSInfo.moveNextToken(SyntaxHighlighting.java:785)
	at org.netbeans.modules.textmate.lexer.SyntaxHighlighting$HSImpl.moveTheSequence(SyntaxHighlighting.java:482)
	at org.netbeans.modules.textmate.lexer.SyntaxHighlighting$HSImpl.moveNext(SyntaxHighlighting.java:431)
	at org.netbeans.modules.editor.lib2.highlighting.DirectMergeContainer$Wrapper.fetchNextHighlight(DirectMergeContainer.java:600)
	at org.netbeans.modules.editor.lib2.highlighting.DirectMergeContainer$HlSequence.updateMergeVars(DirectMergeContainer.java:337)
	at org.netbeans.modules.editor.lib2.highlighting.DirectMergeContainer$HlSequence.nextMerge(DirectMergeContainer.java:303)
	at org.netbeans.modules.editor.lib2.highlighting.DirectMergeContainer$HlSequence.moveNext(DirectMergeContainer.java:234)
	at org.netbeans.modules.editor.lib2.highlighting.HighlightsReader.readUntil(HighlightsReader.java:59)
	at org.netbeans.modules.editor.lib2.view.HighlightsViewFactory.restart(HighlightsViewFactory.java:168)
	at org.netbeans.modules.editor.lib2.view.ViewBuilder$FactoryState.init(ViewBuilder.java:1299)
	at org.netbeans.modules.editor.lib2.view.ViewBuilder.createViews(ViewBuilder.java:699)
	at org.netbeans.modules.editor.lib2.view.ViewBuilder.createReplaceRepaintViews(ViewBuilder.java:660)
	at org.netbeans.modules.editor.lib2.view.ViewUpdates.reinitAllViews(ViewUpdates.java:189)
	at org.netbeans.modules.editor.lib2.view.DocumentViewOp.checkViewsInited(DocumentViewOp.java:621)
	at org.netbeans.modules.editor.lib2.view.DocumentView.getPreferredSpan(DocumentView.java:226)
	at java.desktop/javax.swing.plaf.basic.BasicTextUI$RootView.getPreferredSpan(BasicTextUI.java:1454)
	at java.desktop/javax.swing.plaf.basic.BasicTextUI.getPreferredSize(BasicTextUI.java:950)
	at java.desktop/javax.swing.JComponent.getPreferredSize(JComponent.java:1734)
	at java.desktop/javax.swing.JEditorPane.getPreferredSize(JEditorPane.java:1390)
	at org.netbeans.modules.editor.NbEditorUI$LayeredEditorPane.getPreferredSize(NbEditorUI.java:454)
	at java.desktop/javax.swing.ScrollPaneLayout.layoutContainer(ScrollPaneLayout.java:799)
	at com.formdev.flatlaf.ui.FlatScrollPaneUI$FlatScrollPaneLayout.layoutContainer(FlatScrollPaneUI.java:563)
	at java.desktop/java.awt.Container.layout(Container.java:1541)
	at java.desktop/java.awt.Container.doLayout(Container.java:1530)
	at java.desktop/java.awt.Container.validateTree(Container.java:1725)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validate(Container.java:1660)
	at org.netbeans.core.windows.view.ui.DesktopImpl$LayeredLayout.layoutContainer(DesktopImpl.java:529)
	at java.desktop/java.awt.Container.layout(Container.java:1541)
	at java.desktop/java.awt.Container.doLayout(Container.java:1530)
	at java.desktop/java.awt.Container.validateTree(Container.java:1725)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validateTree(Container.java:1734)
	at java.desktop/java.awt.Container.validate(Container.java:1660)
	at java.desktop/javax.swing.RepaintManager$3.run(RepaintManager.java:757)
	at java.desktop/javax.swing.RepaintManager$3.run(RepaintManager.java:755)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:754)
	at java.desktop/javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1896)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
	at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:136)
[catch] at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Language / Project Type / NetBeans Component

Gradle multi-project

How to reproduce

Copy the following content in the editor (*.toml) and delete the last brace. It wont get deleted because of an exception. Worse can happen if the you add or delete other braces.

[plugins]
jooq-codegen = { id = "org.jooq.jooq-codegen-gradle", version.ref="jooq" }

Did this work correctly in an earlier version?

No / Don't know

Operating System

Windows 10

JDK

Java 21

Apache NetBeans packaging

Apache NetBeans binary zip

Anything else

No response

Are you willing to submit a pull request?

No

Activity

  1. added
    kind:bugBug report or fix
    needs:triageRequires attention from one of the committers
    on Jan 20, 2025
  2. matthiasblaesing commented on Jan 22, 2025

    @matthiasblaesing
    Contributor

    Reproducible, @lkishalmi @vieiro could you please have a look?

  3. self-assigned this
    on Jan 22, 2025
  4. lkishalmi commented on Jan 22, 2025

    @lkishalmi
    Contributor

    Checking.

  5. lkishalmi commented on Jan 22, 2025

    @lkishalmi
    Contributor

    Could not reproduce. However there is something weird in the stacktrace above.

    It has references of org.netbeans.modules.textmate.lexer.SyntaxHighlighting which should not be there.
    Is it possibe that some TextMate grammar get registered in that mime-path?

  6. removed their assignment
    on Jan 22, 2025
  7. changed the title [-]Netbeans hangs when editing TOML files[/-] [+]Netbeans cannot delete some text when editing TOML files[/+] on Jan 23, 2025
  8. vieiro commented on Jan 23, 2025

    @vieiro
    Contributor

    Hi, I can see what @niabot says. In my case NetBeans does not "hang", but can't delete the last } in the given example.

    I'll try to take a look at it later on.

    For the record, here's the message I get in the IDE Log:

    SEVERE [global]
    java.lang.IllegalStateException: Lexer org.netbeans.modules.languages.toml.TomlLexer@419edac2
      returned null token but lexerInput.readLength()=2
      lexer-state: -1
      tokenStartOffset=85, readOffset=87, lookaheadOffset=88
      Chars: "\n\n" - these characters need to be tokenized.
    Fix the lexer to not return null token in this state.
    	at org.netbeans.lib.lexer.LexerInputOperation.checkLexerInputFinished(LexerInputOperation.java:435)
    	at org.netbeans.lib.lexer.LexerInputOperation.nextToken(LexerInputOperation.java:193)
    	at org.netbeans.lib.lexer.inc.TokenListUpdater.relex(TokenListUpdater.java:602)
    	at org.netbeans.lib.lexer.inc.TokenListUpdater.updateRegular(TokenListUpdater.java:255)
    	at org.netbeans.lib.lexer.inc.TokenHierarchyUpdate$UpdateItem.update(TokenHierarchyUpdate.java:325)
    	at org.netbeans.lib.lexer.inc.TokenHierarchyUpdate.processLevelInfos(TokenHierarchyUpdate.java:200)
    	at org.netbeans.lib.lexer.inc.TokenHierarchyUpdate.updateImpl(TokenHierarchyUpdate.java:171)
    	at org.netbeans.lib.lexer.inc.TokenHierarchyUpdate.update(TokenHierarchyUpdate.java:109)
    	at org.netbeans.lib.lexer.TokenHierarchyOperation.textModified(TokenHierarchyOperation.java:585)
    	at org.netbeans.spi.lexer.TokenHierarchyControl.textModified(TokenHierarchyControl.java:71)
    	at org.netbeans.lib.lexer.inc.DocumentInput.textModified(DocumentInput.java:128)
    	at org.netbeans.lib.lexer.inc.DocumentInput.removeUpdate(DocumentInput.java:121)
    	at org.netbeans.lib.editor.util.swing.PriorityDocumentListenerList.removeUpdate(PriorityDocumentListenerList.java:91)
    	at java.desktop/javax.swing.text.AbstractDocument.fireRemoveUpdate(AbstractDocument.java:285)
    	at org.netbeans.editor.BaseDocument.fireRemoveUpdate(BaseDocument.java:1656)
    	at org.netbeans.editor.BaseDocument.handleRemove(BaseDocument.java:1026)
    	at org.netbeans.editor.BaseDocument$FilterBypassImpl.remove(BaseDocument.java:2625)
    	at java.desktop/javax.swing.text.DocumentFilter.remove(DocumentFilter.java:84)
    	at org.openide.text.CloneableEditorSupport$DocFilter.remove(CloneableEditorSupport.java:2361)
    	at org.netbeans.editor.BaseDocument.remove(BaseDocument.java:939)
    	at org.netbeans.editor.BaseKit$DeleteCharAction$3.run(BaseKit.java:2184)
    	at org.netbeans.editor.GuardedDocument.runAtomicAsUser(GuardedDocument.java:333)
    	at org.netbeans.editor.BaseKit$DeleteCharAction.actionPerformed(BaseKit.java:2176)
    	at org.netbeans.modules.csl.core.CslEditorKit$GsfDeleteCharAction.actionPerformed(CslEditorKit.java:375)
    	at org.netbeans.editor.BaseAction.actionPerformed(BaseAction.java:324)
    	at java.desktop/javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1810)
    	at java.desktop/javax.swing.JComponent.processKeyBinding(JComponent.java:2956)
    	at java.desktop/javax.swing.JComponent.processKeyBindings(JComponent.java:3004)
    	at java.desktop/javax.swing.JComponent.processKeyEvent(JComponent.java:2918)
    	at java.desktop/java.awt.Component.processEvent(Component.java:6398)
    	at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4996)
    	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
    	at java.desktop/java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1952)
    	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:883)
    	at java.desktop/java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1146)
    	at java.desktop/java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:1020)
    	at java.desktop/java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:848)
    	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4877)
    	at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    	at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
    	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
    	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
    	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
    	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
    	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
    	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
    	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
    	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
    	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    	at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
    	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
    	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
    	at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:136)
    [catch] at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
    line 2:0 token recognition error at: '\n'
    line 3:0 token recognition error at: '\n'
  9. vieiro commented on Jan 23, 2025

    @vieiro
    Contributor

    I think this may happen in any other antlr4 lexers. The bridge hiccups when the lexer returns null for a token (due to a lexer/parsing error).

    This does not mean that the antlr4 grammar is wrong. The antlr4 [lexer] grammar works correctly for correct files, but can't handle a file with a missing }, for example. For antlr4 grammars to work correctly with the antlr editor bridge, the grammars must contemplate an "error" token and not just return null on incorrect files.

  10. self-assigned this
    on Jan 23, 2025
  11. niabot commented on Jan 24, 2025

    @niabot
    Author

    @vieiro The simple example (deleting the last curly brace) did not "hang" Netbeans. But i also managed to get it stuck in an infinite loop by copying/cutting text. This was my workaround for not being able to type or delete a curly brace. This intial bug might have triggered another bug/effect down the line, but i have no stacktrace/exception of it.

  12. 1 remaining item

  13. lkishalmi commented on Jan 24, 2025

    @lkishalmi
    Contributor

    Managed to reproduce. The issue is in the ANTLR Lexer for TOML

    To reproduce just have the following toml:

    a = {}

    then delete the last curly from right with <backspace>.

    The problem is that ANTLR sends an EOF token in this case, while still having some characters on the stream.

    I can try to patch the bridge to handle this cases better, though it would be the best to fix the TOML Lexer grammar.

  14. lkishalmi commented on Jan 24, 2025

    @lkishalmi
    Contributor

    @vieiro I see this PR in your project. vieiro/toml-java#18

    That could help. Also each mode shall have an rule at the end that matches everything, maps to INVALID_TYPE and/or pops from the mode.

  15. vieiro commented on Jan 24, 2025

    @vieiro
    Contributor

    Thanks @lkishalmi . I'll create a new PR that will help. Basically the lexer will have to return an "error" token whenever an invalid character is found. I'll explain during the weekend.

  16. vieiro commented on Jan 24, 2025

    @vieiro
    Contributor

    That'd be a requirement for all antlr4 grammars that we currently use. The rust grammar does indeed detect these error cases too, IIRC.

  17. added a commit that references this issue on Jan 25, 2025
  18. linked a pull request that will close this issue#8174: Bump ide/libs.tomljava #8192on Jan 25, 2025
  19. vieiro commented on Jan 25, 2025

    @vieiro
    Contributor

    Well, there we go this change

    INLINE_TABLE_UNEXPECTED : . -> type(INVALID_VALUE), popMode;
    INLINE_TABLE_EOF: EOF -> type(INVALID_VALUE), popMode;

    We may want to update the antlr tutorial to explain that antlr4 lexers should contemplate error situation (such as this: a TOML inline table without an ending }) and return this "error token" (INVALID_VALUE in this case). That makes it easier for AntlrLexerBridge to map that token to an ERROR. Just throwing/capturing an exception in Antlr is not good enough for us.

  20. vieiro commented on Jan 25, 2025

    @vieiro
    Contributor

    @vieiro The simple example (deleting the last curly brace) did not "hang" Netbeans. But i also managed to get it stuck in an infinite loop by copying/cutting text. This was my workaround for not being able to type or delete a curly brace. This intial bug might have triggered another bug/effect down the line, but i have no stacktrace/exception of it.

    Hi @niabot , the "hang" you are detecting may be due to your specific setup. As @lkishalmi explains you seem to have a texmate highlighing layer that may be interferring/blocking. Next time you can use jconsole or a jps + jstack combination to fetch an stack trace for us, and report again.

  21. matthiasblaesing commented on Jan 25, 2025

    @matthiasblaesing
    Contributor

    @vieiro @lkishalmi I don't think your assessment is correct, that the user did something special. Have a look here:

    @MimeRegistration(service=HighlightsLayerFactory.class, mimeType="")
    public static class FactoryImpl implements HighlightsLayerFactory {
    @Override
    public HighlightsLayer[] createLayers(Context ctx) {
    Document doc = ctx.getDocument();
    TokenHierarchy<Document> th = TokenHierarchy.get(doc);
    if (th == null) {
    return new HighlightsLayer[0];
    }
    //check the token hierarchy produces the TextmateTokens
    return new HighlightsLayer[] {
    HighlightsLayer.create(SyntaxHighlighting.class.getName(),
    ZOrder.SYNTAX_RACK,
    true,
    new SyntaxHighlighting(doc))
    };
    }
    }

    My reading of this is, that the textmate syntax hightlighter will always run (registered on the empty mimetype). These problem show up at all the locations where the tokensquence is iterated, for the reporter that was syntax highlighting.

  22. vieiro commented on Jan 25, 2025

    @vieiro
    Contributor

    Yep, thanks @matthiasblaesing. We couldn't reproduce the hang with the stacktrace provides, if the fix does not solve the problem then we'll need to reopen with a stack trace.

  23. added 2 commits that reference this issue on Feb 14, 2025
  24. added a commit that references this issue on Feb 27, 2025
  25. added a commit that references this issue on Feb 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions