-
-
Notifications
You must be signed in to change notification settings - Fork 394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(ast): add ContentEq
trait.
#5427
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
CodSpeed Performance ReportMerging #5427 will not alter performanceComparing Summary
|
Merge activity
|
cb78b82
to
23285f4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm late to the party and this has already been merged, but...
As well as specific comments below, a broader thought:
Currently ContentEq
is defined as pub trait ContentEq<Rhs: ?Sized = Self>
. So it allows comparing one type to another type.
I wonder if this makes it broader than it needs to be?
The original problem we needed to solve was something specific: Compare AST nodes while missing out certain fields (span
, scope_id
etc). So I had imagined the scope of ContentEq
being:
- Comparing AST nodes.
- Comparing an AST node to another node of the same type.
In this use case, "content equality" means the nodes have equal "core content", ignoring "context" - "context" being where it sits in AST or source text.
But in this implementation, you've made ContentEq
a much broader thing that could be applied to any type, and allows comparing to any type (including other types). The meaning of "content equality" is implementation-defined, and can be whatever the implementation wants it to.
There are positives and negatives to this:
- Positive: More flexible.
- Negative: Potentially confusing. When it's this broad, what does "content equality" even mean?
To judge the balance between the pluses and minuses, some questions:
- What other uses of "content equality" can we conceive of needing?
- Would those equality relations best be considered "content equality", or would they be better modelled as some other equality relation? e.g. "scope equality" which would have a separate
ScopeEq
trait (I have no idea what "scope equality" would mean, just a spurious example)
In my personal opinion, if we don't have good answers to these questions, making ContentEq
broader than the original use case might be considered "premature abstraction".
We need people to understand the difference between ==
and content_eq
. But that's harder to do if we don't have a solid definition of "content equality".
What do you think @rzvxa?
const IGNORE_FIELDS: [(/* field name */ &str, /* field type */ &str); 5] = [ | ||
("span", "Span"), | ||
("trailing_comma", "Span"), | ||
("scope_id", "ScopeId"), | ||
("symbol_id", "SymbolId"), | ||
("reference_id", "ReferenceId"), | ||
]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we make this a list of types to ignore, rather than field name + type pairs?
I assume we should be ignoring any Span
(regardless of what field it appears in). If we add any new fields which contain a Span
to AST types in future, we'll have to remember to add them here too.
Boshen had to remember to do that in his amends to #5327 (and he did remember), but if this PR wasn't fresh in the mind, it would have been very easy to forget.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure about it since our types aren't context-aware so for less common type names you can have code like this:
// locally used type name.
type ReferenceId = usize;
#[ast]
#[generate_derive(ContentEq)]
struct X {
span: Span,
foo: ReferenceId,
}
Something like ReferenceId
isn't that crazy to be used by someone who isn't aware of this and would mess up their equality checks for good(it is always true in this example).
What if we ignore the Span
type name but use the name + type
combo for the rest? Or we can actually look at the use statements and resolve the type names, I think it would also be a welcomed change in the oxc_regular_expression
crate, Atom
in regex means something else, and our atom is usually used there as use oxc_span::Atom as SpanAtom
, But I had to change it back to Atom
in the ast file to make the codegen recognize it.
Edit:
Now that I'm looking at this with a clear mind I see name + type combo is useless, for a type name such as ReferenceId
it would be common to choose a name like reference_id
as its field identifier. So it doesn't solve anything, It only lowers the surface area of the issue. I'll scrap this idea entirely and go back to checking type names, My point about making it type-aware stays.
I'll submit a follow-up PR addressing these issues and simplifying the implementation. |
Addresses the concerns brought up in #5427
Update the docs for `impl ContentEq for Vec` to state in what circumstances `PartialEq` is faster. See #5427 (comment).
## [0.27.0] - 2024-09-06 - bd820f9 semantic: [**BREAKING**] Remove `SymbolTable::get_symbol_id_from_name` and `SymbolTable::get_scope_id_from_name` (#5480) (overlookmotel) - cba93f5 ast: [**BREAKING**] Add `ThisExpression` variants to `JSXElementName` and `JSXMemberExpressionObject` (#5466) (overlookmotel) - 87c5df2 ast: [**BREAKING**] Rename `Expression::without_parentheses` (#5448) (overlookmotel) ### Features - e8bdd12 allocator: Add `AsMut` impl for `Box` (#5515) (overlookmotel) - 90facd3 ast: Add `ContentHash` trait; remove noop `Hash` implementation from `Span` (#5451) (rzvxa) - 23285f4 ast: Add `ContentEq` trait. (#5427) (rzvxa) - 59abf27 ast, parser: Add `oxc_regular_expression` types to the parser and AST. (#5256) (rzvxa) - 68a1c01 ast_tools: Add dedicated `Derive` trait. (#5278) (rzvxa) - c782916 codegen: Print `type_parameters` in `TaggedTemplateExpression` (#5438) (Dunqing) - 4cb63fe index: Impl rayon related to trait for IndexVec (#5421) (IWANABETHATGUY) - ba4b68c minifier: Remove parenthesized expression for dce (#5439) (Boshen) - ed8ab6d oxc: Conditional expose `oxc_cfg` in `oxc` crate (#5524) (IWANABETHATGUY) - 91b39c4 oxc_diagnostic: Impl DerefMut for OxcDiagnostic (#5474) (IWANABETHATGUY) - 10279f5 parser: Add syntax error for hyphen in `JSXMemberExpression` `<Foo.bar-baz />` (#5440) (Boshen) - 0f50b1e semantic: Check for initializers in ambient `VariableDeclaration`s (#5463) (DonIsaac) - 62f7fff semantic: Check for non-declared, non-abstract object accessors without bodies (#5461) (DonIsaac) - 5407143 semantic: Check for non-declared, non-abstract class accessors without bodies (#5460) (DonIsaac) - 052e94c semantic: Check for parameter properties in constructor overloads (#5459) (DonIsaac) - 32d4bbb transformer: Add `TransformOptions::enable_all` method (#5495) (Boshen) - c59d8b3 transformer: Support all /regex/ to `new RegExp` transforms (#5387) (Dunqing) - cedf7a4 xtask: Impl `as_ast_kind` method for each variant (#5491) (IWANABETHATGUY) ### Bug Fixes - 0df1d9d ast, codegen, linter: Panics in fixers. (#5431) (rzvxa) - fce549e diagnostics: Ignore `Interrupted` and `BrokenPipe` errors while printing (#5526) (Boshen) - ea7a52f napi/transform: Fix test (Boshen) - 9b984b3 regex: Panic on displaying surrogated `UnicodeEscape` characters. (#5469) (rzvxa) - 88b7ddb regular_expression: Handle unterminated character class (#5523) (leaysgur) - 7a797ac semantic: Incorrect reference when `MemberExpression` used in `TSPropertySignature` (#5525) (Dunqing) - d8b9909 semantic: `IdentifierReference` within `TSPropertySignature` cannot reference type-only import binding (#5441) (Dunqing) - 8f9627d transformer: RegExp transform do not transform invalid regexps (#5494) (overlookmotel) - 2060efc transformer: RegExp transform don't transform all RegExps (#5486) (overlookmotel) - cfe5497 transformer: Do not create double reference in JSX transform (#5414) (overlookmotel) - 0617249 transformer/nullish-coalescing-operator: Incorrect reference flags (#5408) (Dunqing) - 0eb32a6 traverse: Invalid variable name generated by `generate_uid_based_on_node` (#5407) (Dunqing)- b96bea4 Add back lifetime (#5507) (IWANABETHATGUY) ### Performance - bfabd8f syntax: Further optimize `is_identifier_name` (#5426) (overlookmotel) - aeda84f syntax: Optimize `is_identifier_name` (#5425) (overlookmotel) - ed8937e transformer: Memoize rope instance (#5518) (Dunqing) - bfab091 transformer: Store needed options only on `RegExp` (#5484) (overlookmotel) - b4765af transformer: Pre-calculate if unsupported patterns in RegExp transform (#5483) (overlookmotel) - 182ab91 transformer: Pre-calculate unsupported flags in RegExp transform (#5482) (overlookmotel) ### Documentation - 64db1b4 ast: Clarify docs for `RegExpPattern` (#5497) (overlookmotel) - 3f204a9 span: Update docs about `ContentEq` `Vec` comparison speed (#5478) (overlookmotel)- 00511fd Use `oxc_index` instead of `index_vec` in doc comments (#5423) (IWANABETHATGUY) ### Refactor - 9f6e0ed ast: Simplify `ContentEq` trait definition. (#5468) (rzvxa) - a43e951 ast: Use loop instead of recursion (#5447) (overlookmotel) - 2224cc4 ast: Renumber `JSXMemberExpressionObject` discriminants (#5464) (overlookmotel) - a952c47 ast: Use loop not recursion (#5449) (overlookmotel) - d9d7e7c ast: Remove `IdentifierName` from `TSThisParameter` (#5327) (overlookmotel) - ccc8a27 ast, ast_tools: Use full method path for generated derives trait calls. (#5462) (rzvxa) - fdb8857 linter: Use "parsed pattern" in `no_div_regex` rule. (#5417) (rzvxa) - e7bd49d regular_expression: Correct typo (#5429) (overlookmotel) - e4ed41d semantic: Change the reference flag to `ReferenceFlags::Type` if it is used within a `TSTypeQuery` (#5444) (Dunqing) - 94a6ac6 span: Use `Hasher` from `std` (#5476) (overlookmotel) - b47aca0 syntax: Use `generate_derive` for `CloneIn` in types outside of `oxc_ast` crate. (#5280) (rzvxa) - a96866d transformer: Re-order imports (#5499) (overlookmotel) - 6abde0a transformer: Clarify match in RegExp transform (#5498) (overlookmotel) - 09c522a transformer: RegExp transform report pattern parsing errors (#5496) (overlookmotel) - dd19823 transformer: RegExp transform do not take ownership of `Pattern` then reallocate it (#5492) (overlookmotel) - 2514cc9 transformer/react: Move all entry points to implementation of Traverse trait (#5473) (Dunqing) - c984219 transformer/typescript: Move all entry points to implementation of Traverse trait (#5422) (Dunqing) ### Styling - 2a43fa4 linter: Introduce the writing style from PR #5491 and reduce the if nesting (#5512) (dalaoshu) ### Testing - 340b535 linter/no-unused-vars: Arrow functions in tagged templates (#5510) (Don Isaac) Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
Part of #5283