Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,217 changes: 1,217 additions & 0 deletions javascript/downgrades/26a123164be893893e2aa0374d820785decf55af/old.dbscheme

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
description: Add variable bindings for 'this'
compatibility: partial
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,7 @@ public Label visit(Program nd, Context c) {
// add all declared global (or module-scoped) names, both non-lexical and lexical
scopeManager.addNames(scopeManager.collectDeclaredNames(nd, isStrict, false, DeclKind.none));
scopeManager.addNames(scopeManager.collectDeclaredNames(nd, isStrict, true, DeclKind.none));
scopeManager.addVariables("this");

visitAll(nd.getBody(), toplevelLabel);

Expand Down Expand Up @@ -1070,6 +1071,9 @@ private void extractFunction(IFunction nd, Label key) {

scopeManager.enterScope((Node) nd);
scopeManager.addNames(locals);
if (!(nd instanceof ArrowFunctionExpression)) {
scopeManager.addVariables("this");
}

// The name of a function expression binds to its own scope.
if (nd.getId() != null && nd instanceof AFunctionExpression) {
Expand Down Expand Up @@ -1541,8 +1545,9 @@ private Label visit(AClass ac, Label key, Node scopeNode, boolean isClassExpress
if (!isClassExpression) {
visit(ac.getId(), key, 0, IdContext.VAR_AND_TYPE_DECL);
}
scopeManager.enterScope(scopeNode);
scopeManager.addVariables("this"); // 'this' in static field initialiers refers to the class
if (ac.hasId() || ac.hasTypeParameters()) {
scopeManager.enterScope(scopeNode);
if (isClassExpression && ac.hasId()) {
scopeManager.addVariables(ac.getId().getName());
scopeManager.addTypeName(ac.getId().getName());
Expand All @@ -1565,9 +1570,7 @@ private Label visit(AClass ac, Label key, Node scopeNode, boolean isClassExpress
addDefaultConstructor(ac);
}
visit(ac.getBody(), key, 2);
if (ac.hasId() || ac.hasTypeParameters()) {
scopeManager.leaveScope();
}
scopeManager.leaveScope();
emitNodeSymbol(ac, key);
return key;
}
Expand Down Expand Up @@ -1893,6 +1896,15 @@ public Label visit(JSXThisExpr nd, Context c) {
return visit((ThisExpression) nd, c);
}

@Override
public Label visit(ThisExpression nd, Context c) {
Label key = super.visit(nd, c);
if (c.idcontext == IdContext.VAR_BIND || c.idcontext == IdContext.VAR_IN_TYPE_BIND) {
addVariableBinding("bind", key, "this");
}
return key;
}

@Override
public Label visit(JSXMemberExpression nd, Context c) {
Comment on lines +1902 to 1909
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR adds binding emission for ThisExpression, but the updated TRAP fixtures in this diff mostly show only the new variables(..., \"this\", ...) entries, not an actual bind relation for a this occurrence. Add at least one extractor test input that contains this usages (e.g., top-level this, non-arrow function this, arrow capturing outer this, and class static field/block this) and assert the resulting TRAP includes the expected bind fact(s) pointing at the correct scope-specific this variable.

Suggested change
if (c.idcontext == IdContext.VAR_BIND || c.idcontext == IdContext.VAR_IN_TYPE_BIND) {
addVariableBinding("bind", key, "this");
}
return key;
}
@Override
public Label visit(JSXMemberExpression nd, Context c) {
addVariableBinding("bind", key, "this");
return key;
}
@Override
public Label visit(JSXMemberExpression nd, Context c) {
public Label visit(JSXMemberExpression nd, Context c) {

Copilot uses AI. Check for mistakes.
Label key = super.visit(nd, c);
Expand Down
136 changes: 73 additions & 63 deletions javascript/extractor/tests/cfg/output/trap/classexpr1.js.trap
Original file line number Diff line number Diff line change
Expand Up @@ -47,74 +47,84 @@ locations_default(#20015,#10000,1,11,1,10)
hasLocation(#20014,#20015)
toplevels(#20001,0)
hasLocation(#20001,#20003)
#20016=*
stmts(#20016,2,#20001,0,"!class {};")
hasLocation(#20016,#20003)
stmt_containers(#20016,#20001)
#20016=@"var;{this};{#20000}"
variables(#20016,"this",#20000)
#20017=*
exprs(#20017,18,#20016,0,"!class {}")
#20018=@"loc,{#10000},1,1,1,9"
locations_default(#20018,#10000,1,1,1,9)
hasLocation(#20017,#20018)
enclosing_stmt(#20017,#20016)
expr_containers(#20017,#20001)
#20019=*
exprs(#20019,80,#20017,0,"class {}")
#20020=@"loc,{#10000},1,2,1,9"
locations_default(#20020,#10000,1,2,1,9)
hasLocation(#20019,#20020)
enclosing_stmt(#20019,#20016)
expr_containers(#20019,#20001)
#20021=*
properties(#20021,#20019,2,0,"constructor() {}")
#20022=@"loc,{#10000},1,8,1,7"
locations_default(#20022,#10000,1,8,1,7)
hasLocation(#20021,#20022)
#20023=*
exprs(#20023,0,#20021,0,"constructor")
hasLocation(#20023,#20022)
enclosing_stmt(#20023,#20016)
expr_containers(#20023,#20001)
literals("constructor","constructor",#20023)
stmts(#20017,2,#20001,0,"!class {};")
hasLocation(#20017,#20003)
stmt_containers(#20017,#20001)
#20018=*
exprs(#20018,18,#20017,0,"!class {}")
#20019=@"loc,{#10000},1,1,1,9"
locations_default(#20019,#10000,1,1,1,9)
hasLocation(#20018,#20019)
enclosing_stmt(#20018,#20017)
expr_containers(#20018,#20001)
#20020=*
exprs(#20020,80,#20018,0,"class {}")
#20021=@"loc,{#10000},1,2,1,9"
locations_default(#20021,#10000,1,2,1,9)
hasLocation(#20020,#20021)
enclosing_stmt(#20020,#20017)
expr_containers(#20020,#20001)
#20022=*
scopes(#20022,8)
scopenodes(#20020,#20022)
scopenesting(#20022,#20000)
#20023=@"var;{this};{#20022}"
variables(#20023,"this",#20022)
#20024=*
exprs(#20024,9,#20021,1,"() {}")
hasLocation(#20024,#20022)
enclosing_stmt(#20024,#20016)
expr_containers(#20024,#20001)
#20025=*
scopes(#20025,1)
scopenodes(#20024,#20025)
scopenesting(#20025,#20000)
#20026=@"var;{arguments};{#20025}"
variables(#20026,"arguments",#20025)
is_arguments_object(#20026)
properties(#20024,#20020,2,0,"constructor() {}")
#20025=@"loc,{#10000},1,8,1,7"
locations_default(#20025,#10000,1,8,1,7)
hasLocation(#20024,#20025)
#20026=*
exprs(#20026,0,#20024,0,"constructor")
hasLocation(#20026,#20025)
enclosing_stmt(#20026,#20017)
expr_containers(#20026,#20001)
literals("constructor","constructor",#20026)
#20027=*
stmts(#20027,1,#20024,-2,"{}")
hasLocation(#20027,#20022)
stmt_containers(#20027,#20024)
is_method(#20021)
exprs(#20027,9,#20024,1,"() {}")
hasLocation(#20027,#20025)
enclosing_stmt(#20027,#20017)
expr_containers(#20027,#20001)
#20028=*
entry_cfg_node(#20028,#20001)
#20029=@"loc,{#10000},1,1,1,0"
locations_default(#20029,#10000,1,1,1,0)
hasLocation(#20028,#20029)
#20030=*
exit_cfg_node(#20030,#20001)
hasLocation(#20030,#20015)
successor(#20016,#20023)
successor(#20024,#20021)
scopes(#20028,1)
scopenodes(#20027,#20028)
scopenesting(#20028,#20022)
#20029=@"var;{this};{#20028}"
variables(#20029,"this",#20028)
#20030=@"var;{arguments};{#20028}"
variables(#20030,"arguments",#20028)
is_arguments_object(#20030)
#20031=*
entry_cfg_node(#20031,#20024)
hasLocation(#20031,#20022)
stmts(#20031,1,#20027,-2,"{}")
hasLocation(#20031,#20025)
stmt_containers(#20031,#20027)
is_method(#20024)
#20032=*
exit_cfg_node(#20032,#20024)
hasLocation(#20032,#20022)
successor(#20027,#20032)
successor(#20031,#20027)
successor(#20023,#20024)
successor(#20021,#20019)
successor(#20019,#20017)
successor(#20017,#20030)
successor(#20028,#20016)
entry_cfg_node(#20032,#20001)
#20033=@"loc,{#10000},1,1,1,0"
locations_default(#20033,#10000,1,1,1,0)
hasLocation(#20032,#20033)
#20034=*
exit_cfg_node(#20034,#20001)
hasLocation(#20034,#20015)
successor(#20017,#20026)
successor(#20027,#20024)
#20035=*
entry_cfg_node(#20035,#20027)
hasLocation(#20035,#20025)
#20036=*
exit_cfg_node(#20036,#20027)
hasLocation(#20036,#20025)
successor(#20031,#20036)
successor(#20035,#20031)
successor(#20026,#20027)
successor(#20024,#20020)
successor(#20020,#20018)
successor(#20018,#20034)
successor(#20032,#20017)
numlines(#10000,1,1,0)
filetype(#10000,"javascript")
166 changes: 86 additions & 80 deletions javascript/extractor/tests/cfg/output/trap/classexpr2.js.trap
Original file line number Diff line number Diff line change
Expand Up @@ -52,91 +52,97 @@ locations_default(#20017,#10000,1,13,1,12)
hasLocation(#20016,#20017)
toplevels(#20001,0)
hasLocation(#20001,#20003)
#20018=*
stmts(#20018,2,#20001,0,"!class A {};")
hasLocation(#20018,#20003)
stmt_containers(#20018,#20001)
#20018=@"var;{this};{#20000}"
variables(#20018,"this",#20000)
#20019=*
exprs(#20019,18,#20018,0,"!class A {}")
#20020=@"loc,{#10000},1,1,1,11"
locations_default(#20020,#10000,1,1,1,11)
hasLocation(#20019,#20020)
enclosing_stmt(#20019,#20018)
expr_containers(#20019,#20001)
#20021=*
exprs(#20021,80,#20019,0,"class A {}")
#20022=@"loc,{#10000},1,2,1,11"
locations_default(#20022,#10000,1,2,1,11)
hasLocation(#20021,#20022)
enclosing_stmt(#20021,#20018)
expr_containers(#20021,#20001)
#20023=*
scopes(#20023,8)
scopenodes(#20021,#20023)
scopenesting(#20023,#20000)
#20024=@"var;{A};{#20023}"
variables(#20024,"A",#20023)
#20025=@"local_type_name;{A};{#20023}"
local_type_names(#20025,"A",#20023)
#20026=*
exprs(#20026,78,#20021,0,"A")
hasLocation(#20026,#20009)
enclosing_stmt(#20026,#20018)
expr_containers(#20026,#20001)
literals("A","A",#20026)
decl(#20026,#20024)
typedecl(#20026,#20025)
#20027=*
properties(#20027,#20021,2,0,"constructor() {}")
#20028=@"loc,{#10000},1,10,1,9"
locations_default(#20028,#10000,1,10,1,9)
hasLocation(#20027,#20028)
stmts(#20019,2,#20001,0,"!class A {};")
hasLocation(#20019,#20003)
stmt_containers(#20019,#20001)
#20020=*
exprs(#20020,18,#20019,0,"!class A {}")
#20021=@"loc,{#10000},1,1,1,11"
locations_default(#20021,#10000,1,1,1,11)
hasLocation(#20020,#20021)
enclosing_stmt(#20020,#20019)
expr_containers(#20020,#20001)
#20022=*
exprs(#20022,80,#20020,0,"class A {}")
#20023=@"loc,{#10000},1,2,1,11"
locations_default(#20023,#10000,1,2,1,11)
hasLocation(#20022,#20023)
enclosing_stmt(#20022,#20019)
expr_containers(#20022,#20001)
#20024=*
scopes(#20024,8)
scopenodes(#20022,#20024)
scopenesting(#20024,#20000)
#20025=@"var;{this};{#20024}"
variables(#20025,"this",#20024)
#20026=@"var;{A};{#20024}"
variables(#20026,"A",#20024)
#20027=@"local_type_name;{A};{#20024}"
local_type_names(#20027,"A",#20024)
#20028=*
exprs(#20028,78,#20022,0,"A")
hasLocation(#20028,#20009)
enclosing_stmt(#20028,#20019)
expr_containers(#20028,#20001)
literals("A","A",#20028)
decl(#20028,#20026)
typedecl(#20028,#20027)
#20029=*
exprs(#20029,0,#20027,0,"constructor")
hasLocation(#20029,#20028)
enclosing_stmt(#20029,#20018)
expr_containers(#20029,#20001)
literals("constructor","constructor",#20029)
#20030=*
exprs(#20030,9,#20027,1,"() {}")
hasLocation(#20030,#20028)
enclosing_stmt(#20030,#20018)
expr_containers(#20030,#20001)
properties(#20029,#20022,2,0,"constructor() {}")
#20030=@"loc,{#10000},1,10,1,9"
locations_default(#20030,#10000,1,10,1,9)
hasLocation(#20029,#20030)
#20031=*
scopes(#20031,1)
scopenodes(#20030,#20031)
scopenesting(#20031,#20023)
#20032=@"var;{arguments};{#20031}"
variables(#20032,"arguments",#20031)
is_arguments_object(#20032)
exprs(#20031,0,#20029,0,"constructor")
hasLocation(#20031,#20030)
enclosing_stmt(#20031,#20019)
expr_containers(#20031,#20001)
literals("constructor","constructor",#20031)
#20032=*
exprs(#20032,9,#20029,1,"() {}")
hasLocation(#20032,#20030)
enclosing_stmt(#20032,#20019)
expr_containers(#20032,#20001)
#20033=*
stmts(#20033,1,#20030,-2,"{}")
hasLocation(#20033,#20028)
stmt_containers(#20033,#20030)
is_method(#20027)
#20034=*
entry_cfg_node(#20034,#20001)
#20035=@"loc,{#10000},1,1,1,0"
locations_default(#20035,#10000,1,1,1,0)
hasLocation(#20034,#20035)
scopes(#20033,1)
scopenodes(#20032,#20033)
scopenesting(#20033,#20024)
#20034=@"var;{this};{#20033}"
variables(#20034,"this",#20033)
#20035=@"var;{arguments};{#20033}"
variables(#20035,"arguments",#20033)
is_arguments_object(#20035)
#20036=*
exit_cfg_node(#20036,#20001)
hasLocation(#20036,#20017)
successor(#20018,#20026)
successor(#20030,#20027)
stmts(#20036,1,#20032,-2,"{}")
hasLocation(#20036,#20030)
stmt_containers(#20036,#20032)
is_method(#20029)
#20037=*
entry_cfg_node(#20037,#20030)
hasLocation(#20037,#20028)
#20038=*
exit_cfg_node(#20038,#20030)
hasLocation(#20038,#20028)
successor(#20033,#20038)
successor(#20037,#20033)
successor(#20029,#20030)
successor(#20027,#20021)
successor(#20026,#20029)
successor(#20021,#20019)
successor(#20019,#20036)
successor(#20034,#20018)
entry_cfg_node(#20037,#20001)
#20038=@"loc,{#10000},1,1,1,0"
locations_default(#20038,#10000,1,1,1,0)
hasLocation(#20037,#20038)
#20039=*
exit_cfg_node(#20039,#20001)
hasLocation(#20039,#20017)
successor(#20019,#20028)
successor(#20032,#20029)
#20040=*
entry_cfg_node(#20040,#20032)
hasLocation(#20040,#20030)
#20041=*
exit_cfg_node(#20041,#20032)
hasLocation(#20041,#20030)
successor(#20036,#20041)
successor(#20040,#20036)
successor(#20031,#20032)
successor(#20029,#20022)
successor(#20028,#20031)
successor(#20022,#20020)
successor(#20020,#20039)
successor(#20037,#20019)
numlines(#10000,1,1,0)
filetype(#10000,"javascript")
Loading