Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Changelog

* use the closest `.luaurc` configuration to each file when bundling code ([#339](https://github.com/seaofvoices/darklua/pull/339))

## 0.19.0

* add `json_lines` content loader and `/zstd`, `/gzip`, `/zlib` encoding variants for `string`, `buffer`, and `bytes` loaders ([#356](https://github.com/seaofvoices/darklua/pull/356))
Expand Down
26 changes: 13 additions & 13 deletions src/rules/bundle/path_require_mode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ pub(crate) enum RequiredResource {
}

#[derive(Debug)]
struct RequirePathProcessor<'a, 'b, 'resources, PathLocatorImpl> {
struct RequirePathProcessor<'a, 'resources, PathLocatorImpl> {
options: &'a BundleOptions,
identifier_tracker: IdentifierTracker,
path_locator: &'b PathLocatorImpl,
path_locator: PathLocatorImpl,
module_definitions: BuildModuleDefinitions,
source: PathBuf,
module_cache: HashMap<PathBuf, Expression>,
Expand All @@ -40,13 +40,13 @@ struct RequirePathProcessor<'a, 'b, 'resources, PathLocatorImpl> {
errors: Vec<String>,
}

impl<'a, 'b, 'resources, PathLocatorImpl: PathLocator>
RequirePathProcessor<'a, 'b, 'resources, PathLocatorImpl>
impl<'a, 'b, 'resources, PathLocatorImpl: PathLocator + Clone>
RequirePathProcessor<'a, 'resources, PathLocatorImpl>
{
fn new<'context, 'code>(
context: &'context Context<'b, 'resources, 'code>,
options: &'a BundleOptions,
path_locator: &'b PathLocatorImpl,
path_locator: PathLocatorImpl,
) -> Self
where
'context: 'b,
Expand Down Expand Up @@ -229,8 +229,8 @@ impl<'a, 'b, 'resources, PathLocatorImpl: PathLocator>
}
}

impl<'a, 'b, 'resources, PathLocatorImpl: PathLocator> Deref
for RequirePathProcessor<'a, 'b, 'resources, PathLocatorImpl>
impl<'a, 'resources, PathLocatorImpl: PathLocator> Deref
for RequirePathProcessor<'a, 'resources, PathLocatorImpl>
{
type Target = IdentifierTracker;

Expand All @@ -239,16 +239,16 @@ impl<'a, 'b, 'resources, PathLocatorImpl: PathLocator> Deref
}
}

impl<'a, 'b, 'resources, PathLocatorImpl: PathLocator> DerefMut
for RequirePathProcessor<'a, 'b, 'resources, PathLocatorImpl>
impl<'a, 'resources, PathLocatorImpl: PathLocator> DerefMut
for RequirePathProcessor<'a, 'resources, PathLocatorImpl>
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.identifier_tracker
}
}

impl<'a, 'b, 'resources, PathLocatorImpl: PathLocator> NodeProcessor
for RequirePathProcessor<'a, 'b, 'resources, PathLocatorImpl>
impl<'a, 'resources, PathLocatorImpl: PathLocator + Clone> NodeProcessor
for RequirePathProcessor<'a, 'resources, PathLocatorImpl>
{
fn process_expression(&mut self, expression: &mut Expression) {
if let Expression::Call(call) = expression {
Expand Down Expand Up @@ -291,7 +291,7 @@ pub(crate) fn process_block(
block: &mut Block,
context: &Context,
options: &BundleOptions,
locator: impl PathLocator,
locator: impl PathLocator + Clone,
) -> Result<(), String> {
if options.parser().is_preserving_tokens() {
log::trace!(
Expand All @@ -311,7 +311,7 @@ pub(crate) fn process_block(
);
}

let mut processor = RequirePathProcessor::new(context, options, &locator);
let mut processor = RequirePathProcessor::new(context, options, locator);
ScopeVisitor::visit_block(block, &mut processor);
processor.apply(block, context)
}
4 changes: 2 additions & 2 deletions src/rules/bundle/require_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl BundleRequireMode {
.map_err(|err| err.to_string())?;

let locator = RequirePathLocator::new(
&require_mode,
require_mode,
context.project_location(),
context.resources(),
);
Expand All @@ -70,7 +70,7 @@ impl BundleRequireMode {
.map_err(|err| err.to_string())?;

let locator = LuauPathLocator::new(
&require_mode,
require_mode,
context.project_location(),
context.resources(),
);
Expand Down
42 changes: 26 additions & 16 deletions src/rules/require/luau_path_locator.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,42 @@
use std::path::{Path, PathBuf};
use std::{
cell::RefCell,
path::{Path, PathBuf},
};

use super::{path_iterator, LuauRequireMode};
use crate::rules::require::path_utils::{get_relative_parent_path, is_require_relative};
use crate::{utils, DarkluaError, Resources};

/// A path locator specifically for Luau require mode that implements
/// the behavior defined in the Luau RFCs for module path resolution.
#[derive(Debug)]
pub(crate) struct LuauPathLocator<'a, 'b, 'resources> {
luau_require_mode: &'a LuauRequireMode,
#[derive(Clone, Debug)]
pub(crate) struct LuauPathLocator<'b, 'resources> {
luau_require_mode: RefCell<LuauRequireMode>,
extra_module_relative_location: &'b Path,
resources: &'resources Resources,
}

impl<'a, 'b, 'c> LuauPathLocator<'a, 'b, 'c> {
impl<'b, 'c> LuauPathLocator<'b, 'c> {
pub(crate) fn new(
luau_require_mode: &'a LuauRequireMode,
luau_require_mode: LuauRequireMode,
extra_module_relative_location: &'b Path,
resources: &'c Resources,
) -> Self {
Self {
luau_require_mode,
luau_require_mode: RefCell::new(luau_require_mode),
extra_module_relative_location,
resources,
}
}

fn load_aliases(&self, source: &Path) -> Result<(), DarkluaError> {
self.luau_require_mode
.borrow_mut()
.load_aliases(source, self.resources)
}
}

impl super::PathLocator for LuauPathLocator<'_, '_, '_> {
impl super::PathLocator for LuauPathLocator<'_, '_> {
fn find_require_path(
&self,
path: impl Into<PathBuf>,
Expand All @@ -39,9 +48,12 @@ impl super::PathLocator for LuauPathLocator<'_, '_, '_> {
path.display(),
source.display()
);
self.load_aliases(source)?;

let require_mode = self.luau_require_mode.borrow();

if is_require_relative(&path) {
if self.luau_require_mode.is_module_folder_name(source) {
if require_mode.is_module_folder_name(source) {
path = get_relative_parent_path(get_relative_parent_path(source)).join(path);
} else {
path = get_relative_parent_path(source).join(path);
Expand All @@ -61,8 +73,7 @@ impl super::PathLocator for LuauPathLocator<'_, '_, '_> {
if source_name == "@self" {
path = get_relative_parent_path(source).join(components);
} else if source_name.starts_with("@") {
let mut extra_module_location = self
.luau_require_mode
let mut extra_module_location = require_mode
.get_source(source_name, self.extra_module_relative_location)
.ok_or_else(|| {
DarkluaError::invalid_resource_path(
Expand All @@ -76,10 +87,9 @@ impl super::PathLocator for LuauPathLocator<'_, '_, '_> {
}

let normalized_path = utils::normalize_path_with_current_dir(&path);
for potential_path in path_iterator::find_require_paths(
&normalized_path,
self.luau_require_mode.module_folder_name(),
) {
for potential_path in
path_iterator::find_require_paths(&normalized_path, require_mode.module_folder_name())
{
if self.resources.is_file(&potential_path)? {
return Ok(utils::normalize_path_with_current_dir(potential_path));
}
Expand All @@ -90,7 +100,7 @@ impl super::PathLocator for LuauPathLocator<'_, '_, '_> {
"tried `{}`",
path_iterator::find_require_paths(
&normalized_path,
self.luau_require_mode.module_folder_name(),
require_mode.module_folder_name(),
)
.map(|potential_path| potential_path.display().to_string())
.collect::<Vec<_>>()
Expand Down
44 changes: 26 additions & 18 deletions src/rules/require/luau_require_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::frontend::DarkluaResult;
use crate::nodes::{Arguments, FunctionCall, StringExpression};
use crate::rules::require::{match_path_require_call, path_utils, LuauPathLocator, PathLocator};
use crate::rules::{Context, RequireMode};
use crate::utils;
use crate::DarkluaError;
use crate::{utils, Resources};

use std::collections::HashMap;
use std::ffi::OsStr;
Expand Down Expand Up @@ -39,6 +39,25 @@ impl Default for LuauRequireMode {
}

impl LuauRequireMode {
pub(crate) fn load_aliases(
&mut self,
luau_file: &Path,
resources: &Resources,
) -> Result<(), DarkluaError> {
if !self.use_luau_configuration {
return Ok(());
}

// Load aliases from .luaurc configuration
if let Some(config) = utils::find_luau_configuration(luau_file, resources)? {
self.luau_rc_aliases.replace(config.aliases);
} else {
self.luau_rc_aliases.take();
}

Ok(())
}

/// Set if the require mode should use `.luaurc` configuration to resolve aliases.
pub fn with_configuration(mut self, use_luau_configuration: bool) -> Self {
self.use_luau_configuration = use_luau_configuration;
Expand All @@ -52,21 +71,7 @@ impl LuauRequireMode {
}

pub(crate) fn initialize(&mut self, context: &Context) -> Result<(), DarkluaError> {
if !self.use_luau_configuration {
self.luau_rc_aliases.take();
return Ok(());
}

// Load aliases from .luaurc configuration
if let Some(config) =
utils::find_luau_configuration(context.current_path(), context.resources())?
{
self.luau_rc_aliases.replace(config.aliases);
} else {
self.luau_rc_aliases.take();
}

Ok(())
self.load_aliases(context.current_path(), context.resources)
}

#[inline]
Expand All @@ -86,8 +91,11 @@ impl LuauRequireMode {
context: &Context,
) -> DarkluaResult<Option<PathBuf>> {
if let Some(literal_path) = match_path_require_call(call) {
let path_locator =
LuauPathLocator::new(self, context.project_location(), context.resources());
let path_locator = LuauPathLocator::new(
self.clone(),
context.project_location(),
context.resources(),
);

let required_path =
path_locator.find_require_path(literal_path, context.current_path())?;
Expand Down
Loading
Loading