Skip to content

Fix/string aware fenced text - #51

Closed
hkimura-intersys wants to merge 2 commits into
intersystems:mainfrom
hkimura-intersys:fix/string-aware-fenced-text
Closed

Fix/string aware fenced text#51
hkimura-intersys wants to merge 2 commits into
intersystems:mainfrom
hkimura-intersys:fix/string-aware-fenced-text

Conversation

@hkimura-intersys

Copy link
Copy Markdown
Member

Overview

This PR extends @isc-tdyar's PR here to use that bug fix (only the string cases) for tsql, ispl, and javascript as well. Details are described in the PR linked. The version is bumped to v1.9.14 as well.

isc-tdyar and others added 2 commits July 25, 2026 05:33
`lex_fenced_text` balances braces without knowing anything about string
literals or comments, so a `{` inside a Python string ends the method body
early. A single line like

    s = "dict literal { unbalanced"

leaves the counter unbalanced, and the body token swallows the rest of the
class. Every following member is lost from the tree, and the only signal is
an ERROR range at the closing brace of the class.

`external_method_body_content` is shared with XData (XML and JSON),
triggers, SQL queries and storage, and the scanner gets no language context
(`in_body` is never read). Teaching `lex_fenced_text` about quotes would
break XML prose containing apostrophes and SQL `--` comments, so this
splits the token instead of patching it in place:

- `_python_method_keywords` and `_python_trigger_keywords` match
  `Language = python` only, so the grammar can select a different body
  token. Both alias `method_keyword_python_language` back to
  `method_keyword_external_language`.
- `python_method_body_content` is lexed by `lex_python_fenced_text`, which
  tracks brace depth while skipping `#` comments, single and triple quotes,
  prefixed strings, and backslash escapes. An unterminated single-quoted
  string stops at the newline so brace counting resumes.
- `method_keyword_external_language` is narrowed to tsql and ispl. Those
  two, plus XData, triggers, queries and storage, keep
  `external_method_body_content` and the existing brace counter.
- The two Python rules in `injections.scm` point at the new token so Python
  highlighting keeps working.

The only change to parser output is `external_method_body_content` ->
`python_method_body_content` on `Language = python` bodies.

The playground grammar keeps its own near-copy of the UDL scanner, so the
same changes are ported there; without that its external token indices skew
and unrelated Owner-keyword tests fail.

New corpus cases in `udl/test/corpus/python-method.txt` cover the brace in a
string, the quoting edge cases (triple quotes, f-strings, raw strings,
escaped quotes, comments, nested dict literals), a Python trigger, and a
tsql method as a control. All five grammars pass: 2745 parses, 0 failures.

Signed-off-by: Thomas Dyar <tdyar@intersystems.com>
The bug described in the commit before this explains how if a
delimiter is included in a string, it was wrongfully counted
in the scanner's parsing of external languages. This was fixed
by Tom Dyar for python, and that fix is extended to other
languages with this commit.
@hkimura-intersys

Copy link
Copy Markdown
Member Author

closing this, as it is being combined with #50 in #52

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.

2 participants