Files
bun.sh/src/css/dependencies.zig
taylor.fish 07cd45deae Refactor Zig imports and file structure (part 1) (#21270)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-07-22 17:51:38 -07:00

152 lines
5.2 KiB
Zig

pub const css = @import("./css_parser.zig");
pub const css_values = @import("./values/values.zig");
const Url = css_values.url.Url;
pub const Error = css.Error;
// const Location = css.Location;
/// Options for `analyze_dependencies` in `PrinterOptions`.
pub const DependencyOptions = struct {
/// Whether to remove `@import` rules.
remove_imports: bool,
};
/// A dependency.
pub const Dependency = union(enum) {
/// An `@import` dependency.
import: ImportDependency,
/// A `url()` dependency.
url: UrlDependency,
};
/// A line and column position within a source file.
pub const Location = struct {
/// The line number, starting from 1.
line: u32,
/// The column number, starting from 1.
column: u32,
pub fn fromSourceLocation(loc: css.SourceLocation) Location {
return Location{
.line = loc.line + 1,
.column = loc.column,
};
}
pub fn hash(this: *const @This(), hasher: *std.hash.Wyhash) void {
return css.implementHash(@This(), this, hasher);
}
pub fn eql(lhs: *const @This(), rhs: *const @This()) bool {
return css.implementEql(@This(), lhs, rhs);
}
};
/// An `@import` dependency.
pub const ImportDependency = struct {
/// The url to import.
url: []const u8,
/// The placeholder that the URL was replaced with.
placeholder: []const u8,
/// An optional `supports()` condition.
supports: ?[]const u8,
/// A media query.
media: ?[]const u8,
/// The location of the dependency in the source file.
loc: SourceRange,
pub fn new(allocator: Allocator, rule: *const css.css_rules.import.ImportRule, filename: []const u8, local_names: ?*const css.LocalsResultsMap, symbols: *const bun.ast.Symbol.Map) ImportDependency {
const supports = if (rule.supports) |*supports| brk: {
const s = css.to_css.string(
allocator,
css.css_rules.supports.SupportsCondition,
supports,
css.PrinterOptions.default(),
null,
local_names,
symbols,
) catch bun.Output.panic(
"Unreachable code: failed to stringify SupportsCondition.\n\nThis is a bug in Bun's CSS printer. Please file a bug report at https://github.com/oven-sh/bun/issues/new/choose",
.{},
);
break :brk s;
} else null;
const media = if (rule.media.media_queries.items.len > 0) media: {
const s = css.to_css.string(allocator, css.MediaList, &rule.media, css.PrinterOptions.default(), null, local_names, symbols) catch bun.Output.panic(
"Unreachable code: failed to stringify MediaList.\n\nThis is a bug in Bun's CSS printer. Please file a bug report at https://github.com/oven-sh/bun/issues/new/choose",
.{},
);
break :media s;
} else null;
const placeholder = css.css_modules.hash(allocator, "{s}_{s}", .{ filename, rule.url }, false);
return ImportDependency{
// TODO(zack): should we clone this? lightningcss does that
.url = rule.url,
.placeholder = placeholder,
.supports = supports,
.media = media,
.loc = SourceRange.new(
filename,
css.dependencies.Location{ .line = rule.loc.line + 1, .column = rule.loc.column },
8,
rule.url.len + 2,
), // TODO: what about @import url(...)?
};
}
};
/// A `url()` dependency.
pub const UrlDependency = struct {
/// The url of the dependency.
url: []const u8,
/// The placeholder that the URL was replaced with.
placeholder: []const u8,
/// The location of the dependency in the source file.
loc: SourceRange,
pub fn new(allocator: Allocator, url: *const Url, filename: []const u8, import_records: *const bun.BabyList(bun.ImportRecord)) UrlDependency {
const theurl = import_records.at(url.import_record_idx).path.pretty;
const placeholder = css.css_modules.hash(
allocator,
"{s}_{s}",
.{ filename, theurl },
false,
);
return UrlDependency{
.url = theurl,
.placeholder = placeholder,
.loc = SourceRange.new(filename, url.loc, 4, theurl.len),
};
}
};
/// Represents the range of source code where a dependency was found.
pub const SourceRange = struct {
/// The filename in which the dependency was found.
file_path: []const u8,
/// The starting line and column position of the dependency.
start: Location,
/// The ending line and column position of the dependency.
end: Location,
pub fn new(filename: []const u8, loc: Location, offset: u32, len: usize) SourceRange {
return SourceRange{
.file_path = filename,
.start = Location{
.line = loc.line,
.column = loc.column + offset,
},
.end = Location{
.line = loc.line,
.column = loc.column + offset + @as(u32, @intCast(len)) - 1,
},
};
}
};
const bun = @import("bun");
const std = @import("std");
const Allocator = std.mem.Allocator;