Skip to content

Commit

Permalink
feat: expose isValidIdentifier utility
Browse files Browse the repository at this point in the history
  • Loading branch information
alekitto committed Nov 5, 2023
1 parent e196275 commit e6717ae
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 3 deletions.
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ const isSimdSupported = WebAssembly.validate(
1, 8, 0, 65, 0, 253, 15, 253, 98, 11,
]),
);
const { compile, prepareStackTrace, start } = isSimdSupported
const { compile, isValidIdentifier, prepareStackTrace, start } = isSimdSupported
? require('./simd/compiler')
: require('./pkg/compiler');

exports._isSimdSupported = isSimdSupported;
exports.compile = compile;
exports.isValidIdentifier = isValidIdentifier;
exports.prepareStackTrace = prepareStackTrace;
exports.start = start;
exports.getReflectionData = require('./lib/reflection').getReflectionData;
Expand Down
38 changes: 36 additions & 2 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ use std::rc::Rc;
use swc_common::comments::SingleThreadedComments;
use swc_common::input::StringInput;
use swc_common::sync::Lrc;
use swc_common::FileName;
use swc_common::{BytePos, FileName};
use swc_ecma_ast::EsVersion;
use swc_ecma_parser::lexer::Lexer;
use swc_ecma_parser::token::{IdentLike, Token, Word};
use swc_ecma_parser::{EsConfig, Parser, Syntax, TsConfig};

mod program;
Expand Down Expand Up @@ -97,9 +98,30 @@ impl CodeParser for &str {
}
}

pub fn is_valid_identifier(input: &str) -> bool {
let lexer = Lexer::new(
Default::default(),
EsVersion::EsNext,
StringInput::new(input, BytePos(0), BytePos(input.len() as u32)),
None,
);

let mut tokens = lexer.into_iter().collect::<Vec<_>>();
if tokens.len() != 1 {
false
} else {
let token = tokens.drain(..).next().unwrap().token;
let Token::Word(Word::Ident(ident)) = token else {
return false;
};

matches!(ident, IdentLike::Other(..))
}
}

#[cfg(test)]
mod tests {
use super::CodeParser;
use super::{is_valid_identifier, CodeParser};
use crate::parser::transformers::decorator_2022_03;
use crate::testing::exec_tr;
use crate::testing::uuid::reset_test_uuid;
Expand Down Expand Up @@ -393,4 +415,16 @@ export default @logger.logged class x {
.compile(Default::default())
.expect("Should compile with no error");
}

#[test]
pub fn should_validate_identifiers() {
assert!(!is_valid_identifier(""));
assert!(!is_valid_identifier("x y z"));
assert!(!is_valid_identifier("export"));
assert!(!is_valid_identifier("abstract"));
assert!(!is_valid_identifier("public"));
assert!(is_valid_identifier("x"));
assert!(is_valid_identifier("y"));
assert!(is_valid_identifier("ident"));
}
}
9 changes: 9 additions & 0 deletions src/wasm/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,12 @@ pub fn compile(
as_module,
})?)
}

#[wasm_bindgen(js_name = isValidIdentifier)]
pub fn is_valid_identifier(input: JsValue) -> bool {
if let Some(s) = input.as_string() {
crate::parser::is_valid_identifier(&s)
} else {
false
}
}
21 changes: 21 additions & 0 deletions tests/wasm/parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const { isValidIdentifier } = require('../..');

describe('Parser', () => {
const identifiers = ['x', 'y', 'ident'];
const invalidIdentifiers = ['', null, 'abstract', 'x y'];

for (const i of identifiers) {
it('should validate js identifier: ' + JSON.stringify(i), () => {
expect(isValidIdentifier(i)).toBeTruthy();
});
}

for (const i of invalidIdentifiers) {
it(
'should validate invalid js identifiers: ' + JSON.stringify(i),
() => {
expect(isValidIdentifier(i)).toBeFalsy();
},
);
}
});

0 comments on commit e6717ae

Please sign in to comment.