mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 02:48:50 +00:00
152 lines
5.2 KiB
Zig
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;
|