Skip to content

Commit

Permalink
chore(span): enable lint warnings on missing docs (#6610)
Browse files Browse the repository at this point in the history
  • Loading branch information
DonIsaac committed Oct 15, 2024
1 parent 3faee66 commit 28b1b4e
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 15 deletions.
9 changes: 9 additions & 0 deletions crates/oxc_span/src/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,28 +26,37 @@ export type Atom = string;
pub struct Atom<'a>(&'a str);

impl Atom<'static> {
/// Get an [`Atom`] containing the empty string (`""`).
#[inline]
pub const fn empty() -> Self {
Atom("")
}
}

impl<'a> Atom<'a> {
/// Borrow a string slice.
#[inline]
pub fn as_str(&self) -> &'a str {
self.0
}

/// Convert this [`Atom`] into a [`String`].
///
/// This is the explicit form of [`Into<String>`], which [`Atom`] also implements.
#[inline]
pub fn into_string(self) -> String {
String::from(self.as_str())
}

/// Convert this [`Atom`] into a [`CompactStr`].
///
/// This is the explicit form of [`Into<CompactStr>`], which [`Atom`] also implements.
#[inline]
pub fn into_compact_str(self) -> CompactStr {
CompactStr::new(self.as_str())
}

/// Convert this [`Atom`] into a [`CompactStr`] without consuming `self`.
#[inline]
pub fn to_compact_str(&self) -> CompactStr {
CompactStr::new(self.as_str())
Expand Down
2 changes: 2 additions & 0 deletions crates/oxc_span/src/cmp.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Specialized comparison traits
/// This trait works similarly to [PartialEq] but it gives the liberty of checking the equality of the
/// content loosely. This would mean the implementor can skip some parts of the content while doing
/// equality checks.
Expand Down
4 changes: 4 additions & 0 deletions crates/oxc_span/src/hash.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//! Specialized hashing traits
use std::{
hash::{Hash, Hasher},
mem::{discriminant, Discriminant},
Expand All @@ -9,6 +10,9 @@ use std::{
///
/// As an example, In AST types we ignore fields such as [crate::Span].
pub trait ContentHash {
/// Hash an AST node based on its content alone.
///
/// This hash ignores node location, but respects precedence and ordering.
fn content_hash<H: Hasher>(&self, state: &mut H);
}

Expand Down
1 change: 1 addition & 0 deletions crates/oxc_span/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Source positions and related helper functions.
//!
//! <https://doc.rust-lang.org/beta/nightly-rustc/rustc_span>
#![warn(missing_docs)]

mod atom;
mod compact_str;
Expand Down
77 changes: 77 additions & 0 deletions crates/oxc_span/src/source_type/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ pub struct SourceType {
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[serde(rename_all = "lowercase")]
pub enum Language {
/// Indicates a JavaScript or JSX file
JavaScript = 0,
/// Indicates a TypeScript file
TypeScript = 1,
/// Indicates a TypeScript definition file (`*.d.ts`)
#[serde(rename = "typescriptDefinition")]
TypeScriptDefinition = 2,
}
Expand Down Expand Up @@ -68,7 +71,10 @@ pub enum ModuleKind {
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[serde(rename_all = "camelCase")]
pub enum LanguageVariant {
/// Standard JavaScript or TypeScript without any language extensions. Stage
/// 3 proposals do not count as language extensions.
Standard = 0,
/// For sources using JSX or TSX
Jsx = 1,
}

Expand Down Expand Up @@ -108,6 +114,9 @@ pub const VALID_EXTENSIONS: [&str; 8] = ["js", "mjs", "cjs", "jsx", "ts", "mts",
impl SourceType {
/// Creates a [`SourceType`] representing a regular [`JavaScript`] file.
///
/// This file could be a vanilla script (no module system of any kind) or a
/// CommonJS file.
///
/// The resulting source type is not a [`module`], nor does it support [`JSX`].
/// Use [`SourceType::jsx`] for [`JSX`] sources.
///
Expand All @@ -132,6 +141,16 @@ impl SourceType {
}
}

/// Creates a [`SourceType`] representing a [`JavaScript`] file using ES6
/// modules. This is akin to a file with an `.mjs` extension.
///
/// ## Example
/// ```
/// # use oxc_span::SourceType;
///
/// let mjs = SourceType::mjs();
/// ```
/// [`JavaScript`]: Language::JavaScript
pub const fn mjs() -> Self {
Self {
language: Language::JavaScript,
Expand All @@ -140,6 +159,13 @@ impl SourceType {
}
}

/// A [`SourceType`] that will be treated as a module if it contains ESM syntax.
///
/// After a file is parsed with an `unambiguous` source type, it will have a final
/// [`ModuleKind`] of either [`Module`] or [`Script`].
///
/// [`Module`]: ModuleKind::Module
/// [`Script`]: ModuleKind::Script
pub const fn unambiguous() -> Self {
Self {
language: Language::JavaScript,
Expand Down Expand Up @@ -230,22 +256,34 @@ impl SourceType {
}
}

/// Mark this source type as a [script].
///
/// [script]: ModuleKind::Script
pub fn is_script(self) -> bool {
self.module_kind == ModuleKind::Script
}

/// Mark this source type as a [module].
///
/// [module]: ModuleKind::Module
pub fn is_module(self) -> bool {
self.module_kind == ModuleKind::Module
}

/// `true` if this [`SourceType`] is [unambiguous].
///
/// [unambiguous]: ModuleKind::Unambiguous
pub fn is_unambiguous(self) -> bool {
self.module_kind == ModuleKind::Unambiguous
}

/// What module system is this source type using?
pub fn module_kind(self) -> ModuleKind {
self.module_kind
}

/// Returns `true` if this is a JavaScript file with or without syntax
/// extensions (like JSX).
pub fn is_javascript(self) -> bool {
self.language == Language::JavaScript
}
Expand All @@ -257,18 +295,29 @@ impl SourceType {
matches!(self.language, Language::TypeScript | Language::TypeScriptDefinition)
}

/// Returns `true` if this is a TypeScript definition file (e.g. `.d.ts`).
pub fn is_typescript_definition(self) -> bool {
self.language == Language::TypeScriptDefinition
}

/// Returns `true` if this source type is using JSX.
///
/// Note that TSX is considered JSX in this context.
pub fn is_jsx(self) -> bool {
self.variant == LanguageVariant::Jsx
}

/// Does this source type implicitly use strict mode semantics?
///
/// Does not consider `"use strict";` directives.
pub fn is_strict(self) -> bool {
self.is_module()
}

/// Mark this [`SourceType`] as a [script] if `yes` is `true`. No change
/// will occur if `yes` is `false`.
///
/// [script]: ModuleKind::Script
#[must_use]
pub const fn with_script(mut self, yes: bool) -> Self {
if yes {
Expand All @@ -277,6 +326,10 @@ impl SourceType {
self
}

/// Mark this [`SourceType`] as a [module] if `yes` is `true`. No change
/// will occur if `yes` is `false`.
///
/// [module]: ModuleKind::Module
#[must_use]
pub const fn with_module(mut self, yes: bool) -> Self {
if yes {
Expand All @@ -287,6 +340,10 @@ impl SourceType {
self
}

/// Mark this [`SourceType`] as [unambiguous] if `yes` is `true`. No change
/// will occur if `yes` is `false`.
///
/// [unambiguous]: ModuleKind::Unambiguous
#[must_use]
pub const fn with_unambiguous(mut self, yes: bool) -> Self {
if yes {
Expand All @@ -295,6 +352,10 @@ impl SourceType {
self
}

/// Mark this [`SourceType`] as using [JavaScript] if `yes` is `true`. No change
/// will occur if `yes` is `false`.
///
/// [JavaScript]: Language::JavaScript
#[must_use]
pub const fn with_javascript(mut self, yes: bool) -> Self {
if yes {
Expand All @@ -303,6 +364,10 @@ impl SourceType {
self
}

/// Mark this [`SourceType`] as using [TypeScript] if `yes` is `true`. No change
/// will occur if `yes` is `false`.
///
/// [TypeScript]: Language::TypeScript
#[must_use]
pub const fn with_typescript(mut self, yes: bool) -> Self {
if yes {
Expand All @@ -311,6 +376,7 @@ impl SourceType {
self
}

/// Mark this [`SourceType`] as a [TypeScript definition] file if `yes` is `true`.
#[must_use]
pub const fn with_typescript_definition(mut self, yes: bool) -> Self {
if yes {
Expand All @@ -319,6 +385,13 @@ impl SourceType {
self
}

/// Mark this [`SourceType`] as using [JSX] if `yes` is `true`. No change
/// will occur if `yes` is `false`.
///
/// When using [TypeScript], this source type now represents a TSX file.
///
/// [JSX]: LanguageVariant::Jsx
/// [TypeScript]: Language::TypeScript
#[must_use]
pub const fn with_jsx(mut self, yes: bool) -> Self {
if yes {
Expand All @@ -327,6 +400,10 @@ impl SourceType {
self
}

/// Disable language extensions (e.g. [JSX]) if `yes` is `true`. No change
/// will occur if `yes` is `false`.
///
/// [JSX]: LanguageVariant::Jsx
#[must_use]
pub const fn with_standard(mut self, yes: bool) -> Self {
if yes {
Expand Down
2 changes: 2 additions & 0 deletions crates/oxc_span/src/span/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,11 +364,13 @@ impl From<Span> for LabeledSpan {

/// Get the span for an AST node
pub trait GetSpan {
/// Get the [`Span`] for an AST node
fn span(&self) -> Span;
}

/// Get mutable ref to span for an AST node
pub trait GetSpanMut {
/// Get a mutable reference to an AST node's [`Span`].
fn span_mut(&mut self) -> &mut Span;
}

Expand Down
21 changes: 6 additions & 15 deletions crates/oxc_span/src/span/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,17 @@ use ::{serde::Serialize, tsify::Tsify};
/// NOTE: `u32` is sufficient for "all" reasonable programs. Larger than u32 is a 4GB JS file.
///
/// ## Hashing
/// [`Span`]'s implementation of [`Hash`] is a no-op so that AST nodes can be
/// compared by hash. This makes them unsuitable for use as keys in a hash map.
///
/// ```
/// use std::hash::{Hash, Hasher, DefaultHasher};
/// use oxc_span::Span;
///
/// let mut first = DefaultHasher::new();
/// let mut second = DefaultHasher::new();
///
/// Span::new(0, 5).hash(&mut first);
/// Span::new(10, 20).hash(&mut second);
///
/// assert_eq!(first.finish(), second.finish());
/// ```
/// [`Span`] has a normal implementation of [`Hash`]. If you want to compare two
/// AST nodes without considering their locations (e.g. to see if they have the
/// same content), use [`ContentHash`](crate::hash::ContentHash) instead.
#[ast]
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
#[non_exhaustive] // Disallow struct expression constructor `Span {}`
pub struct Span {
/// The zero-based start offset of the span
pub start: u32,
/// The zero-based end offset of the span. This may be equal to [`start`](Span::start) if
/// the span is empty, but should not be less than it.
pub end: u32,
}

0 comments on commit 28b1b4e

Please sign in to comment.