Handle mixed type-only imports and exports#194
Conversation
- Preserve runtime bindings for mixed import/export lists while skipping type-only entries - Skip exported interfaces and unsupported typed function signatures gracefully - Add regression tests and docs for types-as-comments behavior
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 6 minutes and 12 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis change implements TypeScript's mixed value/type import and export specifiers (e.g., Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Suite Timing
Measured on ubuntu-latest x64. |
Benchmark Results274 benchmarks Interpreted: 🟢 140 improved · 🔴 92 regressed · 42 unchanged · avg +1.9% arraybuffer.js — Interp: 🟢 13, 1 unch. · avg +10.3% · Bytecode: 🟢 3, 🔴 2, 9 unch. · avg +0.2%
arrays.js — Interp: 🟢 19 · avg +6.3% · Bytecode: 🟢 4, 🔴 10, 5 unch. · avg -0.3%
async-await.js — Interp: 🟢 5, 1 unch. · avg +8.4% · Bytecode: 🔴 4, 2 unch. · avg -1.8%
classes.js — Interp: 🟢 31 · avg +8.2% · Bytecode: 🟢 7, 🔴 1, 23 unch. · avg +2.4%
closures.js — Interp: 🟢 11 · avg +4.2% · Bytecode: 🟢 6, 🔴 1, 4 unch. · avg +1.3%
collections.js — Interp: 🟢 10, 2 unch. · avg +3.2% · Bytecode: 🟢 7, 🔴 3, 2 unch. · avg +2.0%
destructuring.js — Interp: 🟢 12, 🔴 3, 7 unch. · avg +2.8% · Bytecode: 🟢 17, 5 unch. · avg +5.2%
fibonacci.js — Interp: 🟢 4, 4 unch. · avg +1.8% · Bytecode: 🟢 2, 🔴 4, 2 unch. · avg -1.0%
for-of.js — Interp: 🔴 3, 4 unch. · avg -1.3% · Bytecode: 🟢 4, 3 unch. · avg +1.8%
helpers/bench-module.js — Interp: 0 · Bytecode: 0
iterators.js — Interp: 🔴 20 · avg -3.1% · Bytecode: 🟢 12, 🔴 2, 6 unch. · avg +2.7%
json.js — Interp: 🟢 14, 6 unch. · avg +3.4% · Bytecode: 🟢 9, 🔴 1, 10 unch. · avg +1.9%
jsx.jsx — Interp: 🟢 6, 🔴 8, 7 unch. · avg -0.3% · Bytecode: 🟢 1, 🔴 5, 15 unch. · avg -0.5%
modules.js — Interp: 🔴 9 · avg -5.4% · Bytecode: 🟢 6, 🔴 2, 1 unch. · avg -0.4%
numbers.js — Interp: 🟢 4, 🔴 4, 3 unch. · avg +0.4% · Bytecode: 🟢 3, 🔴 1, 7 unch. · avg +0.6%
objects.js — Interp: 🟢 1, 🔴 5, 1 unch. · avg -2.0% · Bytecode: 🟢 4, 3 unch. · avg +2.9%
promises.js — Interp: 🔴 12 · avg -6.9% · Bytecode: 🟢 4, 🔴 1, 7 unch. · avg +0.6%
regexp.js — Interp: 🟢 2, 🔴 7, 2 unch. · avg -1.8% · Bytecode: 🟢 2, 🔴 1, 8 unch. · avg +0.7%
strings.js — Interp: 🔴 8, 3 unch. · avg -3.2% · Bytecode: 🟢 7, 4 unch. · avg +2.3%
typed-arrays.js — Interp: 🟢 8, 🔴 13, 1 unch. · avg +0.4% · Bytecode: 🟢 4, 🔴 1, 17 unch. · avg +0.5%
Measured on ubuntu-latest x64. Benchmark ranges compare cached main-branch min/max ops/sec with the PR run; overlapping ranges are treated as unchanged noise. Percentage deltas are secondary context. |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
units/Goccia.Parser.pas (1)
2340-2358:⚠️ Potential issue | 🟠 MajorAdd lookahead to disambiguate
typebefore treating a named specifier as type-only.The code currently treats any leading
typetoken as a type-only modifier, breaking runtime bindings likeimport { type as kind } from "./m.js"/export { type as kind }. Thetypekeyword is a contextual modifier only when followed by another specifier name; when followed byas,typeis the property name itself.Add a lookahead check: treat
typeas a modifier only when the next token is a valid specifier name (identifier or string), notas. Apply this same check consistently in both import and export specifier loops.Also applies to: 2480-2506
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@units/Goccia.Parser.pas` around lines 2340 - 2358, The parser currently treats any leading KEYWORD_TYPE as a type-only modifier by using Check(gttIdentifier) and Peek.Lexeme, which wrongly marks cases like `import { type as kind }` as type-only; change the logic around IsTypeOnlyBinding so you only treat KEYWORD_TYPE as a modifier when it's followed by a valid specifier name (gttIdentifier or gttString) rather than the `as` token: perform a one-token lookahead (inspect Peek and the next token after Peek) and set IsTypeOnlyBinding true only when Peek is KEYWORD_TYPE AND the following token type is gttIdentifier or gttString, then Advance() to consume the KEYWORD_TYPE; update the same check in the export specifier loop mentioned (the code that mirrors this logic around ConsumeModuleExportName, ImportedNameToken, Match(gttAs), Consume, and Imports.Add) to use the identical lookahead rule.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@units/Goccia.Parser.pas`:
- Around line 2340-2358: The parser currently treats any leading KEYWORD_TYPE as
a type-only modifier by using Check(gttIdentifier) and Peek.Lexeme, which
wrongly marks cases like `import { type as kind }` as type-only; change the
logic around IsTypeOnlyBinding so you only treat KEYWORD_TYPE as a modifier when
it's followed by a valid specifier name (gttIdentifier or gttString) rather than
the `as` token: perform a one-token lookahead (inspect Peek and the next token
after Peek) and set IsTypeOnlyBinding true only when Peek is KEYWORD_TYPE AND
the following token type is gttIdentifier or gttString, then Advance() to
consume the KEYWORD_TYPE; update the same check in the export specifier loop
mentioned (the code that mirrors this logic around ConsumeModuleExportName,
ImportedNameToken, Match(gttAs), Consume, and Imports.Add) to use the identical
lookahead rule.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3b9073b9-5df1-4324-87b2-26606ca9b342
📒 Files selected for processing (9)
docs/design-decisions.mddocs/language-restrictions.mdtests/language/types-as-comments/helpers/exported-interface.jstests/language/types-as-comments/helpers/mixed-type-export.jstests/language/types-as-comments/helpers/type-only-only-side-effect.jstests/language/types-as-comments/helpers/type-only-side-effect.jstests/language/types-as-comments/import-export-type.jstests/language/types-as-comments/unsupported-function-annotations.jsunits/Goccia.Parser.pas
…ction signatures with object return types\n- add regression coverage for object-literal return annotations\n- keep mixed type-only import/export coverage and docs in sync
- Allow `type` export specifiers to be treated as values when followed by a real binding - Add regression tests for imported and re-exported `type`-named values
Summary
type-only specifiers inside mixedimport { ... }andexport { ... }lists while preserving runtime value bindings.export interfacedeclarations as type-only syntax.Testing
tests/language/types-as-comments/for mixed imports/exports andexport interfacehandling.Summary by CodeRabbit
Release Notes
Documentation
Improvements
Tests