Skip to content

Instantly share code, notes, and snippets.

@bgw
Created September 24, 2024 20:36
Show Gist options
  • Save bgw/b7bc0a921cf3e3447acaf8feda60b518 to your computer and use it in GitHub Desktop.
Save bgw/b7bc0a921cf3e3447acaf8feda60b518 to your computer and use it in GitHub Desktop.
astgrep rule for turbopack
language: rust
id: rewrite_vc_self
utils:
self-await:
pattern: self.await?
not: # there are no other ways self is used in this function
inside:
stopBy:
kind: block
inside:
kind: function_item
field: body
has:
kind: self
stopBy:
kind: impl_item
not:
inside:
pattern: self.await?
stopBy: end
transparent-self: # `self.await?` should rewrite to `&self.0`
inside:
kind: impl_item
stopBy:
kind: impl_item
has:
field: type
pattern: $TYPE_NAME
inside:
kind: source_file
stopBy: end
has:
kind: struct_item
has:
field: name
pattern: $TYPE_NAME
follows:
pattern:
context: |
#[turbo_tasks::value]
selector: attribute_item
stopBy:
not:
kind: attribute_item
has:
kind: attribute
has:
field: arguments
has:
pattern: transparent
opaque-self: # `self.await?` should rewrite to `&self`
inside:
kind: impl_item
stopBy:
kind: impl_item
has:
field: type
pattern: $TYPE_NAME
inside:
kind: source_file
stopBy: end
has:
kind: struct_item
has:
field: name
pattern: $TYPE_NAME
follows:
pattern:
context: |
#[turbo_tasks::value]
selector: attribute_item
stopBy:
not:
kind: attribute_item
not:
has:
kind: attribute
has:
field: arguments
has:
pattern: transparent
uses-readref-method: # we'll conservatively bail out if we find any of these patterns
has:
stopBy:
kind: impl_item
any:
- pattern: self.await?.clone_value
- pattern: this.clone_value
- pattern: ReadRef::cell
passes-readref-by-value: # we'll conservatively bail out if it looks like we might pass the readref by value
has:
stopBy:
kind: impl_item
any:
- pattern: self.await?
- pattern: this
not:
inside:
any:
- kind: reference_expression
- kind: field_expression
- kind: let_declaration # N.B.: this is not entirely sound
- kind: assignment_expression
rule:
all:
- pattern: $FUNC
- kind: function_item
- follows:
pattern:
context: |
#[turbo_tasks::function]
selector: attribute_item
stopBy:
not:
kind: attribute_item
- has:
field: parameters
has:
pattern:
selector: parameter
context: |
fn func(self: Vc<$_SELF_TY>) {}
- has:
field: body
has:
matches: self-await
stopBy:
kind: impl_item
- any: # if we can't tell if the struct is transparent or not, just bail out
- matches: transparent-self
- matches: opaque-self
- not:
any:
- matches: uses-readref-method
- matches: passes-readref-by-value
rewriters:
- id: rewrite-self-await-opaque
rule:
all:
- matches: self-await
- matches: opaque-self
fix:
self
- id: rewrite-self-await-transparent
rule:
all:
- matches: self-await
- matches: transparent-self
any:
- inside:
kind: field_expression
pattern: $$$
- inside:
kind: for_expression
field: value
has:
pattern: "&self.await?"
stopBy: end
- pattern: $NEEDS_AMP # only set this metavar if none of the above matches
transform:
MAYBE_AMP:
replace:
source: $NEEDS_AMP
by: "&"
replace: ".+"
fix: "$MAYBE_AMPself.0"
- id: rewrite-self-arg
rule:
pattern:
selector: parameter
context: |
fn func(self: Vc<$_SELF_TY>) {}
fix: "&self"
transform:
NEW_FUNC:
rewrite:
source: $FUNC
rewriters:
- rewrite-self-await-opaque
- rewrite-self-await-transparent
- rewrite-self-arg
fix:
$NEW_FUNC
@bgw
Copy link
Author

bgw commented Sep 24, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment