Skip to content

Add the script-syntax tags that had no token at all - #53

Merged
ghedwards merged 2 commits into
masterfrom
claude/fix-tag-whitelist-47
Aug 13, 2026
Merged

Add the script-syntax tags that had no token at all#53
ghedwards merged 2 commits into
masterfrom
claude/fix-tag-whitelist-47

Conversation

@ghedwards

Copy link
Copy Markdown

Closes #47.

I enumerated instead of guessing

The issue said "cfimap and others" without saying which. The repo ships the answer — cfml.dictionary's syntax dictionaries. Cross-referencing them against cfmlFunction:

  • 118 tags across cf8/9/10/11, cfml7, railo3/4, lucee4.5/5
  • 60 had no token
  • 21 of those are control flow — cfif, cftry, cfreturn, cfparam, cffunction, cfcomponent, cflock, cftransaction … — and already have dedicated grammar rules. Adding them to cfmlFunction would be actively wrong, so they stay out.
  • leaving 39

Prefixed spelling only, and that's the whole design

The issue worried that each new token is a new reserved word. It is — and the bare names here are the worst possible candidates: dump, trace, map, xml, flush, timer, invoke, login, document, textarea, calendar are ordinary functions and variables in real code. dump(...) alone appears in four fixtures in this repo. A bare DUMP token would have reclassified every one of those calls as a tag.

So these 39 get cfdump, cftrace, cfmap … and no bare token. That neutralises the hazard by construction rather than by hoping.

It's a deliberate departure from the aliases added in #29, which map cfX -> type(X) onto an existing bare token. Where no safe bare token can exist, the prefixed spelling stands alone. imap is the single exception — it's the one bare spelling the corpora actually use, so it gets both, with CFIMAP aliasing onto it.

Every new name also goes into the identifier rule, in the same commit. That's the fourth-time-lucky insurance: APPLICATION, INSTANCEOF and CT/NCT each broke working code because the entry came later.

The fixture pins both directions

imap action="close" connection="testImap";     // the tags parse
cfspreadsheet action="read" src="report.xls";
cfdocument format="pdf" { echo("body"); }

dump(results);   trace = 1;   map = {};        // and the names still work
xml = "<a/>";    flush = false;   cfdump = 1;

Verification

  • 313 cfparser tests, ./gradlew build
  • Differential harness 8 → 7, nothing newly broken
  • CFLint 675 against a clean build — 40 new tokens renumber every constant, so this is exactly the case the recompile note in CLAUDE.md is about
  • Fixture fails with cfml.parsing/src/main stashed

Still not complete, by design

The 21 control-flow tags are excluded permanently. The 39 here have prefixed spellings only. If a corpus later needs a bare chart or timer, that's a deliberate decision with a known cost, not an oversight — and the enumeration above makes it a five-minute change rather than an investigation.


Generated by Claude Code

claude added 2 commits August 13, 2026 04:44
Cross-referenced cfmlFunction against the shipped dictionaries rather than
guessing at what was missing: 118 tags across cf8/9/10/11, cfml7, railo and
lucee, of which 60 had no token.

21 of those are control flow -- cfif, cftry, cfreturn, cfparam, cffunction and
the rest -- and already have dedicated grammar rules. Adding them here would
have been wrong, so they stay out. That leaves 39.

Those 39 get their cf-prefixed spelling only. The bare names are the reason:
dump, trace, map, xml, flush, timer, invoke, login and document are ordinary
function and variable names in real code -- dump( ) alone appears in four
fixtures in this repo -- and minting bare tokens for them would have
reclassified every one of those calls as a tag. cfdump carries no such risk.
That is a departure from the cf-prefix aliases added in #29, which map onto an
existing bare token; where no safe bare token can exist, the prefixed spelling
stands alone.

imap is the exception: it is the one bare spelling the corpora actually use, so
it gets both, and CFIMAP aliases onto it.

Every new name is in the identifier rule too. That is the hazard this repo has
hit three times, and adding the entry in the same change is what stops a fourth.
The fixture pins it from both directions: the tags parse, and dump, trace, map,
xml, flush, cfdump and imap all still work as names.

Differential harness 8 disagreements to 7, nothing newly broken. Verified end to
end -- 313 cfparser tests, ./gradlew build, CFLint's 675.

Closes #47

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GzpZFd4rnE1Yi2sVHAji35
The tag names belong in cfmlFunction, which identifier already reaches, so
a variable may still be called cfdump or imap. They were also inserted into
functionModifier, which would have let any of them stand where static,
abstract or final are expected in a function declaration.
@ghedwards
ghedwards merged commit 43ff686 into master Aug 13, 2026
3 checks passed
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.

cfmlFunction's tag list is incomplete — cfimap and others have no token

2 participants