Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

Commit

Permalink
feat(rome_js_semantic): model improvements (#3825)
Browse files Browse the repository at this point in the history
* semantic model improvements
  • Loading branch information
xunilrj authored Nov 23, 2022
1 parent d9c5c14 commit c7f887d
Show file tree
Hide file tree
Showing 30 changed files with 1,788 additions and 1,540 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl Rule for NoNewSymbol {

if reference.has_name("Symbol") {
let model = ctx.model();
let declaration = model.declaration(&reference);
let declaration = model.binding(&reference);

if declaration.is_none() {
return Some(());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,15 @@ impl CallInfo {
fn get_callee(expr: &JsCallExpression, model: &SemanticModel) -> Option<&'static str> {
let callee = expr.callee().ok()?.omit_parentheses();
if let Some(id) = callee.as_reference_identifier() {
if id.has_name("parseInt") && model.declaration(&id).is_none() {
if id.has_name("parseInt") && model.binding(&id).is_none() {
return Some("parseInt()");
}
}

let callee = JsAnyMemberExpression::cast_ref(callee.syntax())?;
let object = callee.get_object_reference_identifier()?;
if object.has_name("Number")
&& model.declaration(&object).is_none()
&& model.binding(&object).is_none()
&& callee.has_member_name("parseInt")
{
return Some("Number.parseInt()");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rome_analyze::{context::RuleContext, declare_rule, ActionCategory, RefactorKind, Rule};
use rome_console::markup;
use rome_diagnostics::Applicability;
use rome_js_semantic::{AllReferencesExtensions, Reference};
use rome_js_semantic::{Reference, ReferencesExtensions};
use rome_js_syntax::{
JsAnyBinding, JsAnyBindingPattern, JsAnyExpression, JsIdentifierExpression,
JsVariableDeclarator,
Expand Down Expand Up @@ -98,7 +98,7 @@ impl Rule for InlineVariable {

for reference in references {
let node = reference
.node()
.syntax()
.parent()?
.cast::<JsIdentifierExpression>()?;

Expand Down
8 changes: 4 additions & 4 deletions crates/rome_js_analyze/src/react.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,15 +180,15 @@ pub(crate) fn is_react_call_api(
if !callee.has_member_name(api_name) {
return false;
}
return match model.declaration(&object) {
return match model.binding(&object) {
Some(decl) => is_react_export(decl, lib),
None => object.has_name(lib.global_name()),
};
}

if let Some(ident) = expr.as_reference_identifier() {
return model
.declaration(&ident)
.binding(&ident)
.and_then(|it| is_named_react_export(it, lib, api_name))
.unwrap_or(false);
}
Expand All @@ -215,7 +215,7 @@ pub(crate) fn jsx_member_name_is_react_fragment(
}

let lib = ReactLibrary::React;
match model.declaration(object) {
match model.binding(object) {
Some(declaration) => Some(is_react_export(declaration, lib)),
None => Some(object.value_token().ok()?.text_trimmed() == lib.global_name()),
}
Expand All @@ -231,7 +231,7 @@ pub(crate) fn jsx_reference_identifier_is_fragment(
name: &JsxReferenceIdentifier,
model: &SemanticModel,
) -> Option<bool> {
match model.declaration(name) {
match model.binding(name) {
Some(reference) => is_named_react_export(reference, ReactLibrary::React, "Fragment"),
None => {
let value_token = name.value_token().ok()?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl Rule for NoArguments {
let name = value_token.text_trimmed();
if name == "arguments" {
let model = ctx.model();
let declaration = model.declaration(reference);
let declaration = model.binding(reference);

if declaration.is_none() {
return Some(());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ impl Rule for NoArrayIndexKey {
// find the declaration and ensure it resolves to the parameter of a function,
// and navigate up to the closest call expression
let parameter = model
.declaration(&reference)
.binding(&reference)
.and_then(|declaration| declaration.syntax().parent())
.and_then(JsFormalParameter::cast)?;
let function = parameter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{semantic_services::Semantic, JsRuleAction};
use rome_analyze::{context::RuleContext, declare_rule, Rule, RuleDiagnostic};
use rome_console::markup;
use rome_js_semantic::ReferencesExtensions;
use rome_js_syntax::{JsCatchClause, JsSyntaxNode};
use rome_rowan::AstNode;

Expand Down Expand Up @@ -68,9 +69,9 @@ impl Rule for NoCatchAssign {
.as_js_identifier_binding()?;
let catch_binding_syntax = catch_binding.syntax();
let mut invalid_assignment = vec![];
for reference in model.all_writes(identifier_binding) {
for reference in identifier_binding.all_writes(model) {
invalid_assignment
.push((reference.node().clone(), catch_binding_syntax.clone()));
.push((reference.syntax().clone(), catch_binding_syntax.clone()));
}

Some(invalid_assignment)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::semantic_services::Semantic;
use rome_analyze::{context::RuleContext, declare_rule, Rule, RuleDiagnostic};
use rome_console::markup;
use rome_js_semantic::{AllReferencesExtensions, Reference};
use rome_js_semantic::{Reference, ReferencesExtensions};
use rome_js_syntax::{JsFunctionDeclaration, JsIdentifierBinding};
use rome_rowan::AstNode;

Expand Down Expand Up @@ -140,7 +140,7 @@ impl Rule for NoFunctionAssign {

let mut hoisted_quantity = 0;
for reference in state.all_writes.iter() {
let node = reference.node();
let node = reference.syntax();
diag = diag.detail(node.text_trimmed_range(), "Reassigned here.");

hoisted_quantity += i32::from(reference.is_using_hoisted_declaration());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::semantic_services::Semantic;
use rome_analyze::{context::RuleContext, declare_rule, Rule, RuleDiagnostic};
use rome_console::markup;
use rome_js_semantic::ReferencesExtensions;
use rome_js_syntax::{
JsDefaultImportSpecifier, JsIdentifierAssignment, JsIdentifierBinding, JsImportDefaultClause,
JsImportNamespaceClause, JsNamedImportSpecifier, JsNamespaceImportSpecifier,
Expand Down Expand Up @@ -89,9 +90,9 @@ impl Rule for NoImportAssign {
.and_then(|binding| {
let ident_binding = binding.as_js_identifier_binding()?;
let model = ctx.model();
for reference in model.all_writes(ident_binding) {
for reference in ident_binding.all_writes(model) {
invalid_assign_list.push((
JsIdentifierAssignment::cast(reference.node().clone())?,
JsIdentifierAssignment::cast(reference.syntax().clone())?,
ident_binding.clone(),
));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::semantic_services::SemanticServices;
use rome_analyze::context::RuleContext;
use rome_analyze::{declare_rule, Rule, RuleDiagnostic};
use rome_console::markup;
use rome_js_semantic::{Binding, DeclarationExtensions};
use rome_js_semantic::{Binding, BindingExtensions};
use rome_js_syntax::{
JsIdentifierAssignment, JsReferenceIdentifier, JsxReferenceIdentifier, TextRange,
};
Expand Down Expand Up @@ -49,26 +49,32 @@ impl Rule for NoRestrictedGlobals {

fn run(ctx: &RuleContext<Self>) -> Self::Signals {
let model = ctx.model();
ctx.query()

let unresolved_reference_nodes = model
.all_unresolved_references()
.chain(model.all_globals())
.filter_map(|reference| {
let node = reference.node().clone();
.map(|reference| reference.syntax().clone());
let global_references_nodes = model
.all_global_references()
.map(|reference| reference.syntax().clone());

unresolved_reference_nodes
.chain(global_references_nodes)
.filter_map(|node| {
let node = AnyIdentifier::unwrap_cast(node);
let (token, declaration) = match node {
let (token, binding) = match node {
AnyIdentifier::JsReferenceIdentifier(node) => {
(node.value_token(), node.declaration(model))
(node.value_token(), node.binding(model))
}
AnyIdentifier::JsxReferenceIdentifier(node) => {
(node.value_token(), node.declaration(model))
(node.value_token(), node.binding(model))
}
AnyIdentifier::JsIdentifierAssignment(node) => {
(node.name_token(), node.declaration(model))
(node.name_token(), node.binding(model))
}
};
let token = token.ok()?;
let text = token.text_trimmed();
is_restricted(text, declaration).map(|text| (token.text_trimmed_range(), text))
is_restricted(text, binding).map(|text| (token.text_trimmed_range(), text))
})
.collect()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl Rule for NoUndeclaredVariables {
ctx.query()
.all_unresolved_references()
.filter_map(|reference| {
let node = reference.node().clone();
let node = reference.syntax().clone();
let node = AnyIdentifier::unwrap_cast(node);
let token = match node {
AnyIdentifier::JsReferenceIdentifier(node) => node.value_token(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rome_analyze::{context::RuleContext, declare_rule, ActionCategory, Rule, Rul
use rome_console::markup;
use rome_diagnostics::Applicability;
use rome_js_factory::make::{ident, js_identifier_binding};
use rome_js_semantic::{AllReferencesExtensions, SemanticScopeExtensions};
use rome_js_semantic::{ReferencesExtensions, SemanticScopeExtensions};
use rome_js_syntax::{
JsClassExpression, JsConstructorParameterList, JsConstructorParameters, JsFunctionDeclaration,
JsFunctionExpression, JsIdentifierBinding, JsParameterList, JsParameters, JsSyntaxKind,
Expand Down Expand Up @@ -237,7 +237,7 @@ impl Rule for NoUnusedVariables {
// Another possibility is if all its references are "inside" the same declaration
if let Some(declarator) = declarator.as_ref() {
let node = declarator.syntax();
if r.node().ancestors().any(|n| n == *node) {
if r.syntax().ancestors().any(|n| n == *node) {
continue;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl Rule for NoConstAssign {
let node = ctx.query();
let model = ctx.model();

let declared_binding = model.declaration(node)?;
let declared_binding = model.binding(node)?;

if let Some(possible_declarator) = declared_binding.syntax().ancestors().find(|node| {
!JsAnyObjectBindingPatternMember::can_cast(node.kind())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
use rome_analyze::{context::RuleContext, declare_rule, ActionCategory, Rule, RuleDiagnostic};
use rome_console::markup;
use rome_diagnostics::Applicability;
use rome_js_semantic::{AllReferencesExtensions, CanBeImportedExported, SemanticModel};
use rome_js_semantic::{CanBeImportedExported, ReferencesExtensions, SemanticModel};
use rome_js_syntax::{
JsFormalParameter, JsFunctionDeclaration, JsFunctionExportDefaultDeclaration,
JsGetterClassMember, JsIdentifierBinding, JsLiteralMemberName, JsMethodClassMember,
Expand Down Expand Up @@ -82,7 +82,7 @@ fn is_non_camel_ok(binding: &JsIdentifierBinding, model: &SemanticModel) -> Opti
}

for reference in binding.all_reads(model) {
let greatparent = reference.node().grand_parent()?;
let greatparent = reference.syntax().grand_parent()?;
if let JS_NEW_EXPRESSION = greatparent.kind() {
return Some(true);
}
Expand Down Expand Up @@ -120,8 +120,9 @@ impl Rule for UseCamelCase {
let name = binding.name_token().ok()?;
let is_camel_case = check_is_camel(name.text_trimmed());
if is_camel_case.is_some() {
let is_jsx_component = model.all_reads(binding).any(|reference| {
JsxReferenceIdentifier::can_cast(reference.node().kind())
let binding = model.as_binding(binding);
let is_jsx_component = binding.all_reads().any(|reference| {
JsxReferenceIdentifier::can_cast(reference.syntax().kind())
});
if !is_jsx_component {
return is_camel_case;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rome_console::markup;

use rome_diagnostics::Applicability;
use rome_js_factory::make;
use rome_js_semantic::{AllReferencesExtensions, Scope, SemanticModel, SemanticScopeExtensions};
use rome_js_semantic::{ReferencesExtensions, Scope, SemanticModel, SemanticScopeExtensions};
use rome_js_syntax::*;
use rome_rowan::{declare_node_union, AstNode, BatchMutationExt};

Expand Down Expand Up @@ -182,7 +182,7 @@ fn check_binding_can_be_const(

// In a for-in or for-of loop or if it has an initializer
if in_for_in_or_of_loop || has_initializer {
return if writes.len() == 0 {
return if writes.next().is_none() {
Some(ConstCheckResult::Fix)
} else {
None
Expand All @@ -195,7 +195,10 @@ fn check_binding_can_be_const(
_ => return None,
};

let host = write.node().ancestors().find_map(DestructuringHost::cast)?;
let host = write
.syntax()
.ancestors()
.find_map(DestructuringHost::cast)?;
if host.has_member_expr_assignment() || host.has_outer_variables(write.scope()) {
return None;
}
Expand Down
Loading

0 comments on commit c7f887d

Please sign in to comment.