support for jsx reference inside the semantic model
MODIFY
crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.js
crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.js
@@ -42,3 +42,7 @@ export function exported_function() {}
function exported_function_2() {}
export { exported_function_2 };
+
+let value;
+function Button() {}
+console.log(<Button att={value}/>);

MODIFY
crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.js.snap
crates/rome_js_analyze/tests/specs/js/noUnusedVariables/noUnusedVariables.js.snap
@@ -49,6 +49,10 @@ export function exported_function() {}
function exported_function_2() {}
export { exported_function_2 };
+let value;
+function Button() {}
+console.log(<Button att={value}/>);
+
```
# Diagnostics

MODIFY
crates/rome_js_semantic/src/events.rs
crates/rome_js_semantic/src/events.rs
@@ -6,7 +6,7 @@ use rome_js_syntax::{
JsAnyAssignment, JsAnyAssignmentPattern, JsAssignmentExpression, JsForVariableDeclaration,
JsIdentifierAssignment, JsIdentifierBinding, JsLanguage, JsReferenceIdentifier, JsSyntaxKind,
JsSyntaxNode, JsSyntaxToken, JsVariableDeclaration, JsVariableDeclarator,
- JsVariableDeclaratorList, TextRange, TextSize,
+ JsVariableDeclaratorList, JsxReferenceIdentifier, TextRange, TextSize,
};
use rome_rowan::{syntax::Preorder, AstNode, SyntaxNodeCast, SyntaxTokenText};
@@ -217,8 +217,8 @@ impl SemanticEventExtractor {
JS_IDENTIFIER_BINDING => {
self.enter_js_identifier_binding(node);
}
- JS_REFERENCE_IDENTIFIER => {
- self.enter_js_reference_identifier(node);
+ JS_REFERENCE_IDENTIFIER | JSX_REFERENCE_IDENTIFIER => {
+ self.enter_reference_identifier(node);
}
JS_IDENTIFIER_ASSIGNMENT => {
self.enter_js_identifier_assignment(node);
@@ -315,14 +315,29 @@ impl SemanticEventExtractor {
Some(())
}
- fn enter_js_reference_identifier(&mut self, node: &JsSyntaxNode) -> Option<()> {
- debug_assert!(matches!(node.kind(), JsSyntaxKind::JS_REFERENCE_IDENTIFIER));
+ fn enter_reference_identifier(&mut self, node: &JsSyntaxNode) -> Option<()> {
+ debug_assert!(matches!(
+ node.kind(),
+ JsSyntaxKind::JS_REFERENCE_IDENTIFIER | JsSyntaxKind::JSX_REFERENCE_IDENTIFIER
+ ));
+ let (name, is_exported) = match node.kind() {
+ JsSyntaxKind::JS_REFERENCE_IDENTIFIER => {
let reference = node.clone().cast::<JsReferenceIdentifier>()?;
let name_token = reference.value_token().ok()?;
- let name = name_token.token_text_trimmed();
+ (
+ name_token.token_text_trimmed(),
+ self.is_js_reference_identifier_exported(node),
+ )
+ }
+ JsSyntaxKind::JSX_REFERENCE_IDENTIFIER => {
+ let reference = node.clone().cast::<JsxReferenceIdentifier>()?;
+ let name_token = reference.value_token().ok()?;
+ (name_token.token_text_trimmed(), false)
+ }
+ _ => return None,
+ };
- let is_exported = self.is_reference_identifier_exported(node);
let current_scope = self.current_scope_mut();
let references = current_scope.references.entry(name).or_default();
references.push(Reference::Read {
@@ -710,7 +725,7 @@ impl SemanticEventExtractor {
}
// Check if a reference is exported and raise the [Exported] event.
- fn is_reference_identifier_exported(&mut self, reference: &JsSyntaxNode) -> bool {
+ fn is_js_reference_identifier_exported(&mut self, reference: &JsSyntaxNode) -> bool {
use JsSyntaxKind::*;
debug_assert!(matches!(reference.kind(), JS_REFERENCE_IDENTIFIER));

MODIFY
crates/rome_js_semantic/src/tests/assertions.rs
crates/rome_js_semantic/src/tests/assertions.rs
@@ -101,7 +101,11 @@ use std::collections::{BTreeMap, HashMap};
/// if(true) ;/*NOEVENT*/;
/// ```
pub fn assert(code: &str, test_name: &str) {
- let r = rome_js_parser::parse(code, 0, SourceType::js_module());
+ let r = rome_js_parser::parse(
+ code,
+ 0,
+ SourceType::js_module().with_variant(rome_js_syntax::LanguageVariant::Jsx),
+ );
if r.has_errors() {
let files = SimpleFile::new(test_name.to_string(), code.into());

MODIFY
crates/rome_js_semantic/src/tests/references.rs
crates/rome_js_semantic/src/tests/references.rs
@@ -124,6 +124,11 @@ assert_semantics! {
ok_scope_function_expression_read2, "let f/*#F1*/ = 1; let g = function f/*#F2*/() {console.log(2, f/*READ F2*/);}; console.log(f/*READ F1*/);",
}
+// Imports
+assert_semantics! {
+ ok_import_used_in_jsx, r#"import A/*#A*/ from 'a.js'; console.log(<A/*READ A*//>);"#,
+}
+
assert_semantics! {
ok_unmatched_reference, r#"a/*?*/"#,
ok_function_expression_read,"let f/*#F*/ = function g/*#G*/(){}; g/*?*/();",

support for jsx reference inside the semantic model (#3055)