Consolidate TypeScript and JavaScript parser resolution#309
Conversation
There was a problem hiding this comment.
inspect review
Triage: 174 entities analyzed | 0 critical, 0 high, 57 medium, 117 low
Verdict: standard_review
Findings (5)
- [low] In
resolve_with_scopes_full, the destructuring ofpre_builtis missingowner_membersbut the else branch creates it. This will cause a compilation error because the tuple sizes don't match. - [low] In
resolve_ref, the function signature addsowner_membersparameter but the BEFORE code shows it's being called without this parameter in multiple places. All call sites need to be updated or this will cause compilation errors. - [low] In
extract_ts_import, the function signature addsts_default_exportsparameter but existing call sites throughout the codebase won't have this parameter, causing compilation errors. - [low] In
resolve_ref, the function now callsis_local_binding_in_scopes_at_byteinstead ofis_local_binding_in_scopes, but this new function doesn't exist in the diff. This will cause a compilation error. - [low] In
resolve_ref, the function changes fromis_local_binding_in_scopestois_local_binding_in_scopes_at_bytewhich adds a byte parameter. Ifis_local_binding_in_scopes_at_bytedoesn't exist or has a different signature, this will cause a compilation error.
Reviewed by inspect | Entity-level triage found 0 high-risk changes
0313d88 to
0b3cc4e
Compare
There was a problem hiding this comment.
inspect review
Triage: 174 entities analyzed | 0 critical, 0 high, 57 medium, 117 low
Verdict: standard_review
Findings (7)
- [low] In
resolve_with_scopes_full, the destructuring ofpre_builtis missingowner_membersbut the else branch creates it. This will cause a compilation error because the tuple sizes don't match. - [low] In
resolve_ref, the function signature addsowner_membersparameter but the function is called from multiple places. If callers weren't updated to pass this new parameter, this will cause compilation errors or runtime issues. - [low] In
extract_ts_import, the function signature addsts_default_exportsparameter but the function is called from other places. If callers weren't updated to pass this new parameter, this will cause compilation errors. - [low] In
resolve_ref, the function now callsis_local_binding_in_scopes_at_byteinstead ofis_local_binding_in_scopes, passingast_ref.byteas a new parameter. Ifis_local_binding_in_scopes_at_bytedoesn't exist or has a different signature, this will cause a compilation error. - [low] In
resolve_with_scopes_full, the destructuring pattern expects 5 values but only 4 are provided whenpre_builtis None. The AFTER code addsowner_membersto the destructuring (5 variables) but the else branch that builds from scratch only initializes 4 variables (symbol_table,class_members,entity_ranges,go_pkg_index), missingowner_members. - [low] In
resolve_ref, the function signature adds a new parameterowner_membersbut all call sites throughout the codebase would need to be updated to pass this parameter. The diff shows the signature change but doesn't show updates to call sites, which would cause compilation errors. - [low] In
extract_ts_import, the function signature adds a new parameterts_default_exportsbut all call sites would need to be updated. The diff shows the signature change but doesn't show corresponding updates to where this function is called.
Reviewed by inspect | Entity-level triage found 0 high-risk changes
rs545837
left a comment
There was a problem hiding this comment.
Performance note on the strip_children_content rewrite.
| .min(content.len()); | ||
|
|
||
| if !child.content.is_empty() && search_start <= search_end { | ||
| if let Some(relative_start) = content[search_start..search_end].find(&child.content) { |
There was a problem hiding this comment.
content[search_start..search_end].find(&child.content) is a naive substring search — O(n×m) where n is the search window and m is the child content length. For large parent entities with many children (e.g. a 500-line class with 30 methods), this adds up.
Since we already computed line_starts and know the child's start line relative to the parent (start_idx), we could jump directly to the expected byte offset:
let expected_offset = line_starts.get(start_idx).copied().unwrap_or(0);
if content[expected_offset..].starts_with(&child.content) {
excluded_ranges.push((expected_offset, expected_offset + child.content.len()));
continue;
}
// fall back to find() only if the direct check failsThis makes the common case O(m) instead of O(n×m).
There was a problem hiding this comment.
Addressed in 1819d73. strip_children_content now first checks the expected line-start offset with starts_with, and only falls back to the bounded .find() search if that direct match fails.
0b3cc4e to
1819d73
Compare
There was a problem hiding this comment.
inspect review
Triage: 174 entities analyzed | 0 critical, 0 high, 57 medium, 117 low
Verdict: standard_review
Findings (7)
- [low] In
resolve_with_scopes_full, the destructuring ofpre_builtexpects 5 fields but only 4 are provided in the tuple. The BEFORE code has 4 fields(symbol_table, class_members, entity_ranges, go_pkg_index)but AFTER expects 5 fields(symbol_table, class_members, owner_members, entity_ranges, go_pkg_index). This will cause a compilation error or runtime panic. - [low] In
resolve_ref, the function signature adds a new parameterowner_membersbut the function is called from multiple places. If any call site wasn't updated to pass this new parameter, it will cause a compilation error. The diff shows the signature change but doesn't show all call sites being updated. - [low] In
extract_ts_import, the function signature adds a new parameterts_default_exportsbut the function is called from other places. If any call site wasn't updated to pass this new parameter, it will cause a compilation error. - [low] In
resolve_ref, the function call changed fromis_local_binding_in_scopes(scope_idx, scopes, name)tois_local_binding_in_scopes_at_byte(scope_idx, scopes, name, ast_ref.byte). This is a breaking change - ifis_local_binding_in_scopes_at_bytedoesn't exist or has different semantics thanis_local_binding_in_scopes, this will cause a compilation error or incorrect behavior. - [low] In
resolve_with_scopes_full, the destructuring pattern expects 5 values but only 4 are provided whenpre_builtis None. The code tries to destructure(symbol_table, class_members, owner_members, entity_ranges, go_pkg_index)but the else branch only builds 4 values withoutowner_members. - [low] In
extract_ts_import, a new parameterts_default_exportsis added to the function signature, but all call sites in the codebase would need to be updated to pass this parameter. This is a breaking change that will cause compilation errors at all call sites. - [low] In
resolve_ref, a new parameterowner_membersis added between existing parameters, but this is a breaking change. All call sites would need to be updated to pass this new parameter in the correct position.
Reviewed by inspect | Entity-level triage found 0 high-risk changes
1819d73 to
c10963f
Compare
There was a problem hiding this comment.
inspect review
Triage: 181 entities analyzed | 0 critical, 0 high, 60 medium, 121 low
Verdict: standard_review
Findings (6)
- [low] In
resolve_with_scopes_full, the destructuring ofpre_builtis missingowner_membersin the tuple pattern, causing a compile error. The BEFORE code destructures 4 fields(pb.symbol_table, pb.class_members, pb.entity_ranges, pb.go_pkg_index)but the AFTER code destructures 5 fields(pb.symbol_table, pb.class_members, pb.owner_members, pb.entity_ranges, pb.go_pkg_index). However, the else branch still builds only 4 fields, creating a type mismatch. - [low] In
resolve_ref, the function signature adds a new parameterowner_membersbut the function is called from multiple places. The diff shows the signature changed from 11 parameters to 12 parameters, but we don't see corresponding updates to all call sites in the diff, which would cause compilation errors at those call sites. - [low] In
extract_ts_import, the function signature adds two new parametersts_default_exportsandtop_level_entities, but the diff doesn't show updates to all call sites. This function is likely called fromextract_imports_from_astor similar functions, and those call sites would fail to compile without the new arguments. - [low] In
resolve_ref, the function now callsis_local_binding_in_scopes_at_byte(scope_idx, scopes, name, ast_ref.byte)instead ofis_local_binding_in_scopes(scope_idx, scopes, name). However, the diff doesn't show the definition ofis_local_binding_in_scopes_at_byte, and if this function doesn't exist or has a different signature, this will cause a compilation error. - [low] In
resolve_ref, the function signature addsowner_membersparameter but the BEFORE code shows it's being called without this parameter in multiple places, which will cause compilation errors at all call sites. - [low] The function
is_local_binding_in_scopesis renamed tois_local_binding_in_scopes_at_bytewith an additionalbyteparameter, but this will break all existing call sites that use the old function name.
Reviewed by inspect | Entity-level triage found 0 high-risk changes
|
Pushed a runtime performance follow-up in What changed:
Validation:
|
c10963f to
14c8aa0
Compare
There was a problem hiding this comment.
inspect review
Triage: 179 entities analyzed | 0 critical, 0 high, 60 medium, 119 low
Verdict: standard_review
Findings (7)
- [low] In
resolve_reffunction, the new parameterowner_membersis added but the function signature inextract_ts_importdoesn't match -extract_ts_importpassests_default_exportsandtop_level_entitiesbutresolve_refexpectsowner_membersin that position, causing a parameter mismatch. - [low] Function
is_local_binding_in_scopes_at_byteis called inresolve_refbut this function name doesn't exist in the codebase - the original function wasis_local_binding_in_scopes. This will cause a compilation error. - [low] In
build_ts_default_export_table, the function callsdefault_export_names_from_contentwhich uses regex patterns that may incorrectly match export statements inside comments or strings, leading to false positive default export detection. - [low] In
default_export_names_from_content, the regexDEFAULT_SPECIFIER_REchecks if the next content starts with 'from ' to skip re-exports, but this check happens after capturing the match. If there's whitespace or comments between the closing brace and 'from', the check will fail and incorrectly treat a re-export as a local export. - [low] In
build_import_table, the regexJS_DEFAULT_REwill incorrectly match and capture the default import even when it's followed by named imports in braces (e.g.,import Foo, { bar } from './module'), but the regex doesn't account for the comma and named imports, potentially causing incorrect parsing. - [low] In
resolve_default_export_target, if multiple files have the same default export name, the function returns the first match fromsorted_fileswithout considering thatfind_import_filemight return a different file than what's in the default exports table, causing a potential mismatch. - [low] In
build_export_alias_edges, the function filters for entities withentity_type == "export"and looks them up inimport_tableusing(file_path, name)as key. However, the import_table is built for imports, not exports, so this lookup will likely fail for most export entities, making the function ineffective.
Reviewed by inspect | Entity-level triage found 0 high-risk changes
14c8aa0 to
16e2b72
Compare
There was a problem hiding this comment.
inspect review
Triage: 184 entities analyzed | 0 critical, 0 high, 60 medium, 124 low
Verdict: standard_review
Findings (7)
- [low] In
resolve_with_scopes_full, the function signature addsowner_membersparameter but the destructuring in theelsebranch doesn't initialize it, causing a compilation error. Theelsebranch buildssymbol_table,class_members,entity_ranges, andgo_pkg_indexbut never createsowner_members, yet the return statement expects 5 values includingowner_members. - [low] In
resolve_ref, the function signature addsowner_membersparameter but the function body is truncated in the diff. However, all call sites toresolve_refwould need to be updated to pass this new parameter, and if they weren't updated, this would cause compilation errors. - [low] In
extract_ts_import, the function signature adds two new parametersts_default_exportsandtop_level_entitiesbut the function body is truncated. All call sites toextract_ts_importmust be updated to pass these parameters, otherwise compilation will fail. - [low] In
is_local_binding_in_scopes_at_bytecall withinresolve_ref, the function name changed fromis_local_binding_in_scopestois_local_binding_in_scopes_at_byteand now takes an additionalast_ref.byteparameter. If this function doesn't exist or has a different signature, this will cause a compilation error. - [low] In
find_import_file, the function returnsOption<&'a str>but the last line is truncated asfind(|path| file_stem(path) == source_mod. This appears to be missing the closing parenthesis and the rest of the expression, which would cause a syntax error. - [low] In
default_export_names_from_content, the regexDEFAULT_SPECIFIER_REmatches export specifiers but the code checksif local_name == "default"to identify default exports. However, this logic is backwards - inexport { foo as default },local_namewould be "default" andoriginal_namewould be "foo", so the code should pushoriginal_namenot check iflocal_name == "default". - [low] In
build_import_table, the code handles re-exports withif original_name == "default"to resolve default exports, but for the non-default case it callsfind_import_targetwhich returnsOption<&String>and then calls.cloned()on it. However, the result is assigned totarget_idwhich should beString, notOption<String>, causing a type mismatch in the subsequentif let Some(target_id).
Reviewed by inspect | Entity-level triage found 0 high-risk changes
16e2b72 to
a56d6dc
Compare
There was a problem hiding this comment.
inspect review
Triage: 209 entities analyzed | 0 critical, 0 high, 83 medium, 126 low
Verdict: standard_review
Findings (7)
- [low] In
resolve_reffunction, the parameteris_local_binding_in_scopes_at_byteis called but the function signature shows it was previouslyis_local_binding_in_scopes. The new function name includes_at_byteand takes an additionalast_ref.byteparameter, but there's no evidence in the diff that this function exists or was added. This will cause a compilation error. - [low] In
find_import_filefunction, the return type isOption<&'a str>but the function returnscandidate_path.as_str()which has lifetime tied to the localcandidatesvector, not to the inputcandidate_file_pathsslice. This creates a dangling reference sincecandidatesis dropped at the end of the function scope. - [low] In
default_export_names_from_content, the function truncates at the first newline when checkingonly_js_ts_statement_trivia, but the regexDEFAULT_IDENTIFIER_REcan match identifiers that span multiple lines or have complex expressions after them. The line_tail calculationcontent[name.end()..].split_once('\n').map_or(&content[name.end()..], |(line, _)| line)only checks the first line, which could incorrectly classify multi-line statements. - [low] In
resolve_with_scopes_full, the destructuring ofPreBuiltLookupsaddsowner_membersbut the else branch that builds from scratch only declareslet mut symbol_tableandlet mut class_memberswithout declaringowner_members. This will cause a compilation error when trying to useowner_memberslater in the function. - [low] In
extract_ts_import, the function signature adds two new parametersts_default_exports: &TsDefaultExportTableandtop_level_entities: &OnceLock<TopLevelEntityIndex>, but there's no evidence in the diff that these parameters are actually used in the function body or that callers have been updated to pass these arguments. This will cause compilation errors at call sites. - [low] In
resolve_reffunction, the new parameterowner_membersis added but the function signature inextract_ts_importdoesn't match -extract_ts_importnow has 2 new parameters (ts_default_exportsandtop_level_entities) butresolve_refis called from within scope resolution logic that may not have these parameters available, causing a potential compilation error or missing argument bug. - [low] In
find_import_file, the fallback path at the end returnsfile_stem(path)comparison result but tries to return the path itself. The function signature expectsOption<&'a str>butcandidates.into_iter().find(...)returns an element from the localcandidatesvector which doesn't have the correct lifetime 'a.
Reviewed by inspect | Entity-level triage found 0 high-risk changes
a56d6dc to
3b55e0c
Compare
There was a problem hiding this comment.
inspect review
Triage: 219 entities analyzed | 0 critical, 0 high, 86 medium, 133 low
Verdict: standard_review
Findings (7)
- [low] In
strip_children_content, the function attempts to find child content within a search window but doesn't handle the case where the child content spans multiple lines with different indentation. The search usessearch_window.starts_with(&child.content)andsearch_window.find(&child.content)which require exact string matches, but the child content may have been extracted with different whitespace normalization than what appears in the parent content. - [low] In
resolve_ref, the function signature adds a new parameterowner_membersbut the call sites in the diff are not shown. If existing call sites were not updated to pass this new parameter, it will cause compilation errors or runtime issues. - [low] In
extract_ts_import, the function signature adds two new parametersts_default_exportsandtop_level_entitiesbut the diff doesn't show the function body being updated to use these parameters. If the function is called but doesn't use these parameters, it suggests incomplete implementation. - [low] In
find_import_file, the function returnsOption<&'a str>but the code snippet is truncated atfind(|path| file_stem(path) == source_mod. This appears to be missing the closing parenthesis and the rest of the expression, which would cause a compilation error. - [low] In
build_import_table, the code buildsowned_contentHashMap and then extendscontent_mapwith references to it. However,owned_contentis a local variable that will be dropped at the end of the function scope, making all the string references incontent_mapdangling pointers. - [low] In
resolve_with_scopes_full, the destructuring ofPreBuiltLookupsaddsowner_membersbut the BEFORE code shows it destructures into 4 variables while AFTER shows 5. The struct definition change is not shown, so ifPreBuiltLookupswasn't updated to includeowner_members, this will cause a compilation error or field mismatch. - [low] In
is_local_binding_in_scopes_at_byte, the function name changed fromis_local_binding_in_scopesand now takes an additionalbyteparameter, but the implementation is not shown. If the function body wasn't updated to actually use thebyteparameter for position-aware checking, it could lead to incorrect scope resolution.
Reviewed by inspect | Entity-level triage found 0 high-risk changes
3b55e0c to
71741b4
Compare
There was a problem hiding this comment.
inspect review
Triage: 221 entities analyzed | 0 critical, 0 high, 87 medium, 134 low
Verdict: standard_review
Findings (7)
- [low] In
find_import_file, the function returnsOption<&'a str>but the last line is truncated and appears to return a comparison result instead of finding the matching path. The code showscandidates.into_iter().find(|path| file_stem(path) == source_modwhich is incomplete and likely missing the closing parenthesis and the actual return logic. - [low] In
resolve_with_scopes_full, the BEFORE code extractsclass_membersfromPreBuiltLookupsbut the AFTER code extracts bothclass_membersandowner_members. However, the BEFORE code showslet mut class_members: HashMap<String, Vwhich is truncated. Ifowner_memberswas added toPreBuiltLookupsbut the unpacking in the else branch wasn't updated to initialize it, this would cause a compilation error or logic bug. - [low] In
resolve_ref, the function signature adds a new parameterowner_membersbut the call sites inresolve_with_scopes_fullmay not be updated to pass this parameter. The diff shows the signature change but doesn't show all call sites being updated, which would cause a compilation error or incorrect behavior if some calls are missing the argument. - [low] In
resolve_ref, the BEFORE code callsis_local_binding_in_scopes(scope_idx, scopes, name)but the AFTER code callsis_local_binding_in_scopes_at_byte(scope_idx, scopes, name, ast_ref.byte). This changes the function signature being called, but ifis_local_binding_in_scopes_at_bytedoesn't exist or has different semantics, this would break the logic for detecting local bindings. - [low] In
build_import_table, the code buildsowned_contentHashMap but then extendscontent_mapwith references to it. However,owned_contentis a local variable that will be dropped at the end of the function scope. The code showscontent_map.extend(owned_content.iter().map(|(file_path, content)| (file_path.as_str(), content.as_str())))which creates references with lifetime tied toowned_content, but then usescontent_mapafter this point, potentially creating dangling references. - [low] In
resolve_with_scopes, the function now callsresolve_with_scopes_fullwith 7 parameters (adding twoNonevalues), but based on the signature change ofresolve_with_scopes_full, the 7th parameter ispre_built_import_table: Option<&HashMap<(String, String), String>>. However, the function is being called withNone, Nonewhich means bothpre_builtandpre_built_import_tableare None, but there's no indication thatowner_membersis being passed, suggesting a parameter count or ordering issue. - [low] In
build_import_table, the code changes from usingunwrap_or_default()to manually buildingcontent_mapandowned_content. The new code reads files for non-Go files that aren't incontent_map, but then it only adds toowned_contentif the file read succeeds. However, the subsequent code that buildsts_default_exportsexpects all JS/TS files to be incontent_map. If a JS/TS file fails to read, it won't be incontent_map, causingbuild_ts_default_export_tableto silently skip it, which could lead to incorrect import resolution.
Reviewed by inspect | Entity-level triage found 0 high-risk changes
|
@Iron-Ham — #308 just went in and this has conflicts now. Needs a rebase onto main before we can merge. Thanks! I have started realizing why weave-crdts is even more of an interesting thing to have because multiple PRs affecting the same files in a codebase make it a little hard to sort out merge conflicts. |
👀 FWIW, I think this set of work that's open now would have been better represented as a stack of open PRs but that's not something GitHub supports through fork PRs 🫠 |
71741b4 to
f0faa46
Compare
There was a problem hiding this comment.
inspect review
Triage: 115 entities analyzed | 0 critical, 0 high, 48 medium, 67 low
Verdict: standard_review
Findings (7)
- [low] In
find_import_file, the function returnsOption<&'a str>but the last line is truncated and appears to be missing the complete return statement. The code showscandidates.into_iter().find(|path| file_stem(path) == source_modwhich is incomplete - it's missing the closing parenthesis and the rest of the expression. - [low] In
build_import_table, the code checksif file_path.ends_with(".go") || content_map.contains_key(filebut the condition is incomplete/truncated. This will cause a compilation error. - [low] In
resolve_with_scopes_full, the function signature adds a new parameterpre_built_import_table: Option<&HashMap<(String, String), String>>but the corresponding call inresolve_with_scopespassesNonefor both the last two parameters. However, the destructuring in the BEFORE code shows(symbol_table, class_members, entity_ranges, go_pkg_index)(4 items) while AFTER shows(symbol_table, class_members, owner_members, entity_ranges, go_pkg_index)(5 items). This mismatch will cause a compilation error whenpre_builtisSomebecause the tuple destructuring expects 5 items butPreBuiltLookupsstruct only has 4 fields in the old code. - [low] In
resolve_ref, there's a logic error where the code checks for entity types"module" | "variable" | "object"before checking for"class" | "struct" | "interface". If an entity matches both conditions (which shouldn't happen but the code structure allows), the first branch will execute and potentially miss class member lookups. More critically, the first branch usesowner_membersandlookup_owned_scope_memberwhile the second usesclass_members, but both checkinfo.name == receiver, suggesting they might be handling the same case differently. - [low] In
build_import_table, the code createsowned_content: HashMap<String, String>but the variable is declared as mutable and appears to be used for reading file content for files not incontent_map. However, the diff is truncated and doesn't show how this HashMap is populated or used, suggesting incomplete code that may not compile or function correctly. - [low] In
build_import_table, the code creates a mutablecontent_mapand then tries to extend it, but then creates a separateowned_contentHashMap. The logic appears incomplete as shown by the truncated lineif file_path.ends_with(".go") || content_map.contains_key(file. This incomplete condition will cause a compilation error. - [low] In
resolve_ref, there's a logic change where the code now checks for"module" | "variable" | "object"entity types before checking for"class" | "struct" | "interface". However, the second condition useselse ifwhich means if an entity is both a module AND matches the class/struct/interface check, only the first branch executes. This could miss valid class member lookups if an entity somehow satisfies both conditions.
Reviewed by inspect | Entity-level triage found 0 high-risk changes
|
Yeah it was basically an idea I have been chasing with sem and weave is to think of the file system and the search primitives from first principles now. Because most of our analysis is not line by line or file by file at the moment. It's basically on top of weave's working and the CRDT layer on top adds proactive prevention, agents claim entities before editing so concurrent edits on the same function are caught before branches even exist, so that as a concept makes the most sense to me at the moment. |
Summary
Supersedes #303, #305, #291, #289, #288, #285.
Fixes #264.
Fixes #262.
Fixes #265.
Closes #267.
Fixes #266.
Fixes #263.
Test plan