Improving Bean Shell Support in Playground#4780
Open
shai-almog wants to merge 76 commits intomasterfrom
Open
Conversation
Static nested classes
- ScriptedClass.build now recognises nested BSHClassDeclaration children
with the `static` modifier and evaluates them eagerly against the
parent's static namespace.
- BSHAllocationExpression.lookupScriptedClass walks dotted names like
`Outer.Inner` by resolving the first segment as a ScriptedClass and
then descending through each enclosing class's static namespace.
- Manual `.`-split (avoid CN1's restricted String.split which fails the
compliance check).
- `class_decl/static_inner` flips EVAL_ERROR -> SUCCESS.
Top-level anonymous SAM rewrite
- New rewriteTopLevelAnonSams pass converts statement-level
`new Runnable() { public void run() {...} }` and similar
expressions for the SAM types LambdaValue implements
(Runnable, Supplier, Consumer, BiConsumer, Function, Predicate,
Comparator) into __lambdaSupport.lambda(...) calls.
- The conversion is restricted to that hard-coded set so it doesn't
intercept anonymous implementations of user-declared scripted
interfaces (those have their own anon-class path that needs the user's
method bodies).
- `class_decl/inner_anonymous_runnable` flips EVAL_ERROR -> SUCCESS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previously enum constants were materialised with an empty backing
namespace and a single __enumName__ field. Constants like
`LOW(1), HIGH(10)` ignored their arguments, so reading `Prio.LOW.v`
returned the field's default rather than 1.
ScriptedClass.populateEnumConstants now uses the standard newInstance
path for each constant, threading the declared constructor arguments
through. Field initialisers and the constructor body run normally.
__enumName__ is set on the resulting instance namespace afterwards.
Per-constant body blocks (Op.ADD { public int apply(...) {...} })
remain unsupported — they would need a per-constant subclass with its
own method overrides.
Matrix
- enum_decl/with_fields_unsupported renames to with_fields and flips
EVAL_ERROR -> SUCCESS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The arrow-form rewrite already turned `case <e> -> <r>;` into
`case <e>: var = <r>; break;`. The yield form preserves traditional
case-label structure but uses `yield <expr>;` to emit the result —
which BSH's existing parser doesn't recognise.
PlaygroundRunner now post-processes switch-expression bodies that
don't contain arrows by replacing each top-level
`yield <expr>;` with `<varName> = <expr>; break;`. Combined with the
existing declaration-hoisting, this lets users write:
String s = switch (x) {
case 1: yield "one";
default: yield "?";
};
Limitations
- The yield rewrite is a flat scan that ignores switch nesting; a
yield inside an inner switch expression would also be rewritten with
the outer variable, which is wrong. This rare combination is left as
a follow-up.
Matrix
- switch_expr/yield_form_unsupported renames to yield_form and flips
PARSE_ERROR -> SUCCESS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`enum Op { ADD { public int apply(...) {...} } ... }` — each constant
can now have its own block body that supplies method overrides. The
constant becomes an instance of an anonymous subclass whose parent is
the declared enum type.
Implementation
- ScriptedClass.populateEnumConstants checks each BSHEnumConstant for a
BSHBlock child. When present, build an anonymous subclass via the
existing ScriptedClass.build path (declaring namespace = enum's
declaring scope, parent = the enum class itself, body = the
per-constant block) and instantiate it. When absent, instantiate the
enum class directly.
- The enum class's own non-abstract default method (e.g.
`public int apply(int a, int b) { return 0; }`) is inherited by
constants without an override, satisfying call sites that don't
override on every constant. Abstract methods are documented as
unsupported.
Matrix
- enum_decl/with_method_per_constant_unsupported renames to
with_method_per_constant and flips EVAL_ERROR -> SUCCESS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Now that LambdaValue implements common java.util.function SAMs (Runnable, Function, Predicate, Comparator, Supplier, Consumer, BiConsumer), registry-dispatched method calls like Collections.sort(list, comparator) should accept a lambda directly — but the generator's matchesType check returned false for any LambdaValue not in a hardcoded SAM-bridge list, so calls that wanted a java.util.Comparator (which LambdaValue implements) were rejected. Generator change - matchesType now also accepts LambdaValue when type.isInstance(value) is true, in addition to the existing CN1-specific listener bridge fallback. - adaptValue takes a fast path that returns the LambdaValue unchanged when the target type is one it directly implements, instead of routing through adaptLambdaValue's hardcoded wrappers. - Regenerated registry — diff is a one-line change applied to every per-package matchesType emit site. Matrix - New `integration/lambda_to_collections_sort` case exercises Collections.sort with a comparator lambda; was EVAL_ERROR, now SUCCESS. - Five additional integration cases added (record_in_list, two_level_inheritance, interface_with_default_used, switch_expr_in_method_return, lambda_method_ref_combo) — all SUCCESS. - Total cases now 126. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
super(args) in scripted-class constructors - Inside a subclass ctor body, `super(arg1, arg2, ...)` now forwards to the matching ctor template on the parent ScriptedClass, bound to the current instance namespace. Implementation lives in Name.invokeLocalMethod: when the bare method name is "super" and there's a ScriptedInstance on the call stack with a parent, dispatch to ScriptedClass.findConstructorTemplate(args). - New matrix case `class_decl/super_constructor_call` exercises a base ctor that initializes a field plus a derived ctor that calls super(v) and adds its own initialization. java.util.stream registry inclusion - Drop `java.util.stream` from the generator's exclusion list so Stream/Collector/Collectors are at least *resolvable* as classes. - The actual stream() entry point is unavailable because CN1's java.util.Collection backport doesn't expose stream(). Documented with a `stream_unsupported` matrix case. Total cases now 128. Two remain as documented negative tests. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Method dispatch on ScriptedInstance previously matched by name+arity
only, so calls like `m.fmt(\"hi\")` against
`class M { String fmt(int n); String fmt(String s); }` picked the first
arity-1 template (the int one) and failed at parameter coercion.
ScriptedClass.findInstanceMethodTemplate now scores same-arity
templates against the actual argument types and returns the highest-
scoring one. Exact class match scores 3, isInstance scores 2,
primitive-compatible scores 2, untyped/Object-typed scores 1, and
mismatch scores -5. Ties resolve to the first declared template.
The primitive-compatibility helper avoids `Boolean.TYPE`/`Character.TYPE`
because CN1's restricted Boolean/Character don't expose those static
fields (compliance check would fail).
Three new integration matrix cases — method_overloading,
ctor_overloading, iterator_walk — all SUCCESS. Total 131.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
README - Replace the "Limitations" section's outdated bullets with an accurate capability inventory mirroring what the syntax matrix asserts. The old section said classes, interfaces, enums, method references, and TWR were unsupported — all of those work now. - Document the remaining real gaps (non-static inner classes, runtime reflection, and Collection.stream()). Matrix - New `integration/class_implements_scripted_interface` case verifies that a regular class can implement a script-declared interface. - New `integration/comparator_natural_order` case sorts a list with a Comparator lambda built via `(a, b) -> a.compareTo(b)`. - Total cases now 133. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three bugs surfaced by 10 new advanced integration cases:
Multi-level super dispatch
- `class A -> B -> C` where each B.m() calls super.m() and C.m() calls
super.m() was infinite-looping. findScriptedThis always returned the
actual instance's class, so super.m() from inside B resolved to B's
parent (A) — but ALSO when inside C.m()'s super call into B, the
nested super.m() still saw C.getClass() and looped back to B.
- Added a ThreadLocal dispatch-class stack on ScriptedClass. Pushed on
super-method entry, popped on exit. Name's super-dispatch consults
this stack first, falling back to the instance's class when empty.
Chained supers now walk up the inheritance chain as expected.
Nested switch expressions
- `switch(...) { case 2 -> switch(...) { ... }; ... }` parse-errored
because rewriteSwitchExpressions only ran one pass. The inner switch
was produced textually inside a case body after the outer rewrite
turned its case body into an assignment, so we never saw it.
- rewriteSwitchExpressions now loops until a fixed point (capped at 16
iterations as a safety).
Per-constant enum anon subclass visibility + enum-ness
- `enum S { OPEN { ... return CLOSED; ... }, CLOSED { ... } }` failed
because (a) the anon subclass used the declaring namespace as parent,
so sibling constants (`CLOSED`) weren't visible from OPEN's body, and
(b) the anon wasn't marked as enum, so the built-in name()/ordinal()
dispatch in ScriptedInstance skipped it.
- populateEnumConstants now declares each anon against the enum's
static namespace (sibling constants resolve) and propagates
markEnum(true) to the anon.
Ten new integration matrix cases exercise these combinations:
three_level_inheritance, recursion_factorial, enum_implements_interface,
interface_extends_interface, builder_pattern, custom_exception_hierarchy,
nested_switch_expressions, record_with_static_factory,
enum_used_in_switch, state_machine_via_enum. All SUCCESS.
Total cases now 143.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New SUCCESS cases - integration/field_init_at_declaration — `int x = 42;` in class body - integration/list_of_records — sorted list of record-typed values - integration/generic_method_on_class — generic method with T return - integration/multi_dim_array — nested enhanced-for on int[][] - integration/interface_with_two_methods — class implementing a non-SAM scripted interface with two methods. New documented gap cases - integration/twr_with_var_unsupported — `try (var r = ...)` not accepted by BSH's TWR grammar (type must be declared explicitly). - integration/exception_with_cause_chain_unsupported — super(args) forwarded to a Java superclass (RuntimeException) is a no-op, so the cause chain breaks. Subclassing Java exceptions beyond the single message form is best done by throwing a raw RuntimeException. Total cases now 150. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
record equality, map keyset walk, protected method dispatch — all SUCCESS. Plus three documented registry gaps: - map_entryset_iteration — Map.Entry nested interface not exposed - stringbuilder_* — all StringBuilder ctors missing from registry (under investigation; `new StringBuilder(\"\")` and `new StringBuilder()` both fail) - arrays_aslist — varargs Arrays.asList not wired Each gap has a companion SUCCESS case that uses the supported workaround (keySet, `+=` concatenation, manual list build). Total cases now 160; two pre-existing negative tests remain (enhanced_for/null_array and interface_decl/cannot_instantiate). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ApiClass.isLookupOnly() hardcoded `java.lang.StringBuilder` as lookup-only, meaning the generator emitted only the class entry for it and no constructor / method dispatch blocks. The comment (no longer there, removed implicitly by its absence) suggested this was a workaround for an older emit limitation with StringBuilder's final varargs append overloads; the current emitter handles those fine. Dropping the special case lets `new StringBuilder()`, `new StringBuilder(String)`, and the full append-chain run. Matrix - The two previously-EVAL_ERROR stringbuilder cases flip to SUCCESS: stringbuilder_no_arg and stringbuilder_with_initial. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New SUCCESS cases
- visitor_pattern — interface + concrete implementation + caller
- factory_method_returning_interface — static factory returning an
anonymous Shape implementation
- chained_method_calls_returning_this — fluent builder with return this
- static_method_calling_other_static — static dispatch within a class
- generic_container — Box<T> parameterised two different ways
- conditional_with_sideeffects_substitute — ternary using array access
(without post-increment, which isn't supported on subscripted elements)
New documented gap
- array_element_increment_unsupported — `a[0]++` hits a BSH unary-op
limitation ("Unary operation `++` inappropriate for object"). The
workaround (`a[0] = a[0] + 1`) works.
Total cases now 167.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`public static <T> List<T> asList(T... array)` was being dropped
because resolveSimpleName("T") returned null — method-level type
parameters aren't tracked in the class-level typeParameterBounds. Since
generic type parameters erase to Object at runtime anyway, short
all-uppercase names (T, U, V1, K, etc.) that otherwise resolve to
nothing are now treated as java.lang.Object.
This unblocks a range of generic utility methods on JDK classes:
Arrays.asList, Arrays.copyOf(T[],int), Collections methods with
`<T>` signatures, etc.
Matrix
- integration/arrays_aslist_unsupported renames to arrays_aslist and
flips EVAL_ERROR -> SUCCESS.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Array-element access (a[0] on int[]) returns a boxed Integer rather than a Primitive, so `a[0]++` hit BSHUnaryExpression.unaryOperation's "inappropriate for object" branch. Same issue for array-of-any-wrapper and fields returning boxed numerics. BSHUnaryExpression now wraps Number/Character operands into a Primitive before delegating to Operators.unaryOperation. The wrap uses the typed Primitive constructors since the Object-typed one is private. Matrix - array_element_increment_unsupported -> array_element_increment (EVAL_ERROR -> SUCCESS). - New array_element_postfix_decrement case (SUCCESS). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nested lambda bug - `Function<Integer, Function<Integer, Integer>> adder = a -> b -> a + b;` failed with "Unable to parse code syntax" because the outer lambda's body was normalised (prepended with `return`) BEFORE its inner lambda was rewritten. The normalised body `return b -> a + b;` couldn't be re-processed as a lambda expression (the prefix is `return b`, not a valid parameter list). - rewriteTopLevelLambdas now recurses on the raw body before normalisation, so nested arrows get unwound outer-to-inner. New integration cases (all SUCCESS) - nested_lambdas - array_access_in_ternary - class_with_static_field_used_via_instance - method_ref_in_sort (via Integer.compare inside a comparator) - long_chain_calls (method chaining on a freshly-constructed generic) - cast_of_scripted_instance (Object → ScriptedInstance cast) Total cases now 173. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`try (var in = new StringReader(\"hi\"))` crashed with an NPE inside BSHAutoCloseable.eval — `var` resolves to null Type, and then `AutoCloseable.class.isAssignableFrom(null)` threw. BSHAutoCloseable now: - Only fails the upfront AutoCloseable check when the type is known (declared explicitly). `var` bypasses it. - After the declarator runs, verifies the bound value actually implements AutoCloseable when the type was inferred. Matrix - integration/twr_with_var_unsupported renames to twr_with_var and flips EVAL_ERROR -> SUCCESS. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All SUCCESS. Exercises common real-world patterns: - exception_across_methods — try/catch inside one method catching an exception thrown by another method on the same scripted class. - return_inside_lambda_block — early-return from a block-bodied lambda. - multiple_anonymous_impls — two anon implementations of the same scripted interface coexisting in the same scope. - generic_class_with_generic_method — Box<T> with an additional method-level type parameter <U>. - enum_switch_with_yield — yield form for an enum-discriminant switch. - record_toString_format — implicit record.toString() in `+` context. - class_with_private_helper_method — private instance method called from another instance method on the same class. - loop_accumulating_into_list — classic for loop filling an ArrayList followed by an enhanced-for sum. Total cases now 181. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- bounded_generic_type — `class NumberBox<T extends Number>` with `val.doubleValue()` calling through to Number's method. - string_equals / string_substring_indexof — common String API patterns. - integer_parse_and_format — Integer.parseInt round-trip. - container_with_multiple_buttons — builds a container with listeners in a loop and verifies getComponentCount. - form_layout_switching — creates a FlowLayout container then switches its layout to BoxLayout. - hashset_basic — HashSet dedup. - linked_list_as_queue — LinkedList.add / removeFirst. Total cases now 189. Remaining documented gaps: 5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Java implicitly widens char to int in numeric contexts, so
`s.indexOf(' ')` on CN1's `indexOf(int ch)` should work — but the
registry's matchesType required value instanceof Number, rejecting
Character. The emitted cast also went through ((Number) x).intValue()
which fails for Character.
Generator changes
- matchesType now accepts Character for byte/short/int/long/float/
double param slots.
- castValue for those types calls a new emitted toIntValue(Object)
helper that handles both Number and Character.
Regenerated registry. Matrix includes a new string_indexof_char_widens
case that calls `s.indexOf(' ')` directly.
Total cases now 190.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All SUCCESS. Covers patterns I had not yet exercised: - instanceof_array_type — `o instanceof int[]`. - final_local_variable — a `final` local that's used read-only. - long_arithmetic / bitwise_long_ops — long literals, shifts, bitwise. - scripted_class_as_map_key — ScriptedInstance as a HashMap key (identity hashing is fine, since we don't override equals/hashCode). - multi_return_paths — method with three early returns. - this_in_listener_captures_field — a scripted class registering a listener on a passed-in button; the listener body mutates the class's own field through the captured lambda scope. Total cases now 197. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All SUCCESS. Exercises: - triple_nested_enhanced_for — 3D int array traversed with nested enhanced-for. - labeled_outer_break_with_search — classic nested-loop search that breaks out of the outer loop via a label. - try_finally_side_effect — try body and finally both mutating the same captured array, verifying finally runs. - null_check_then_use — null-guard ternary on a local String. - abstract_template_method — abstract Base.doubled() calls abstract getNum() which the subclass supplies (classic template method). - chained_ternary — nested ternary expressions in a single statement. Total cases now 203. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`class Dog implements Named` where Named declares a default method didn't pick up the default — only explicit `extends` merged parent methods. Now `implements` is walked too: - BSHClassDeclaration.eval gathers scripted interfaces from the AST children after the optional extends-name and passes them alongside the parent to ScriptedClass.build. - ScriptedClass.build merges each interface's instance methods into this class's method table when they aren't shadowed by a concrete declaration or a parent-class method. - A new convenience build overload keeps call sites that have no interfaces (enum anon subclasses) compiling without changes. Ten new integration cases (interface_default_calling_abstract, enum identity/switch patterns, Math operations, rethrow, static field sharing, 3-level polymorphism, finally-after-return, etc.) — all SUCCESS. Total cases now 212. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All SUCCESS. Covers classic design patterns and common API ops: - observer_pattern — multiple listeners subscribed to a Bus emit-loop - decorator_pattern — Excited wraps Basic greeter, double-wrap chains - map_of_list — Map<String, List<String>> with nested generic mutations - continue_in_loop — basic classic for-loop with continue - string_starts_ends_with / string_char_at_and_length — common String API - deeply_nested_conditions — four-level nested if/else - enum_iter_if_else — E.values() iteration with per-constant behaviour Total cases now 220. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Eight SUCCESS, one documented gap. New SUCCESS - generic_interface_scripted — `interface Mapper<T, R>` with anonymous one-off impl. - throwing_scripted_exception — scripted class extending RuntimeException used in throw/catch. - array_literal_in_call — Arrays.asList receiving an explicit Integer[] (bypasses varargs inference). - null_coalesce_via_ternary — simple null-guard ternary. - sequence_of_if_returns — Validator method with four early returns. - collections_sort_natural_order — Collections.sort(List) default order. - class_shadowing_imported_type — script-defined Button shadows CN1's. - record_with_primitive_components — tests the common primitive case. Documented gap - nested_records_unsupported — when a record component's type is another scripted class, the pre-declared field (typed Object) isn't correctly updated by the canonical ctor's `this.left = left`. Use primitive or Java-class component types as a workaround. Total cases now 229. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`this.field = value` on a ScriptedInstance previously returned a LOOSETYPE_FIELD LHS whose assign() calls setTypedVariable(varName, Types.getType(val), ...). When the field had been pre-declared with a different resolved type (e.g. a scripted-class-typed field resolving to Object), the re-typed assignment didn't cleanly update the pre- existing variable. Switching to a VARIABLE LHS (localVar=true) routes through setLocalVariableOrProperty which updates the value without re-declaring the variable's type. The nested-records case that exposed this still has another subtle interaction (field is resolved on the declaring-namespace chain rather than the instance-namespace chain when both contain a class called Inner); leaving as a documented gap for follow-up, but the LHS fix is a prerequisite. Matrix is stable at 229 cases; no flips in this commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lambda-body passes
- rewriteTopLevelLambdas now also threads the body through
rewriteSwitchExpressions and rewriteArrowSwitchStatements before
normalisation. `n -> { String s = switch (n) { ... }; return s; }`
previously failed at lambda-invocation time because the body was
stringified verbatim and BSH's eval of it doesn't run the playground
rewrites. Enables `switch_in_lambda_body` (flipped to SUCCESS).
Null-callstack guards
- BSHType.resolvesToScriptedClass and BSHAllocationExpression
.lookupScriptedClass now short-circuit when the callstack is null
rather than NPE'ing. Observed in paths where the allocation is
exercised through a non-standard entry point (some nested-generic
field-decl eval).
Matrix
- 10 new cases (visitor-style observer, decorator, nested generic,
deeply nested conditions, enum iter, internal/external field
assignment variants...). 238 total; two new documented gaps noted:
two_classes_typed_cross_ref_unsupported and
external_field_assignment_unsupported (with internal setter
workaround demonstrated).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SUCCESS - cn1_container_border_layout — Container with BorderLayout slots. - cn1_textfield_and_listener — TextField with ActionListener. - cn1_button_chain_setters — Button UIID + enabled state setters. - collections_reverse_then_check — Collections.reverse. - function_chain_via_scripted_class — method dispatch chain in a scripted class. - varargs_like_user_method — `int... xs` in a user-declared class. Documented gaps - interface_constant_unqualified_unsupported — interface constants aren't visible from an implementing class's method body without qualification. Qualify with `Iface.NAME`. - interface_constant_qualified_unsupported — qualified access also fails because static field resolution on scripted interfaces cross- references an unresolved field path that hits the same callstack- null issue as other external scripted-field access. Tracked with the related external_field_assignment / two_classes_cross_ref limitations. Total cases now 246. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Java spec: fields declared in an interface are implicitly `public static final`. ScriptedClass.build wasn't honouring that — fields without an explicit `static` modifier were deferred to the instance-field list, so `Config.DEFAULT_NAME = "world"` inside an interface was never evaluated and never bound in Config's static namespace. ScriptedClass.build now takes a `treatFieldsAsStatic` flag; when an interface is being declared it's set to true and all field decls are evaluated into the static namespace. BSHClassDeclaration passes the flag based on `type == Type.INTERFACE`. Matrix: interface_constant_qualified flips EVAL_ERROR -> SUCCESS (246/246). The unqualified companion remains as a documented gap — implementing classes still don't walk their implemented-interface static namespaces for bare name lookups. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All SUCCESS. Exercises: - boolean_short_circuit_and / boolean_short_circuit_or — verifying that && / || really short-circuit (no side-effect, no div-by-zero). - scripted_class_returned_from_method — a factory returning a scripted-class instance. - nested_enhanced_for_with_continue — skip-even sum on a 2D array. - complex_predicate_with_and_or — composing two Predicate lambdas. - enum_with_multiple_fields — enum constants with two args each. - enum_method_returning_self — enum method returning enum constants. - method_parameter_shadowing_field — `this.x + x` disambiguating a parameter shadowing a field. Total cases now 254. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.