Compare commits

...

9 Commits

Author SHA1 Message Date
autofix-ci[bot]
d2f39f7d2d [autofix.ci] apply automated fixes 2025-09-29 09:30:05 +00:00
Claude Bot
dc82103b88 Fix empty-prefix containment issue in fromNameAndPrefix
Normalize empty VendorPrefix to .none to prevent it from matching everything
in the contains() check. Without this fix, an empty VendorPrefix would
incorrectly match against any allowed prefixes.

The fix adds:
- const normalized_pre = if (pre.isEmpty()) VendorPrefix{ .none = true } else pre;
- Uses normalized_pre in both the contains() check and when constructing the result

This ensures that empty prefixes are properly handled and don't inadvertently
match all vendor prefixes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 09:26:41 +00:00
Jarred Sumner
f8d1b2a6d5 Delete completed.md 2025-09-29 00:59:55 -07:00
autofix-ci[bot]
89481a8cd5 [autofix.ci] apply automated fixes 2025-09-29 07:57:56 +00:00
Claude Bot
7ecb4a520e Optimize CSS properties generation with EnumMap and combined cases
Improvements to the CSS properties generator script:

1. **Optimized fromNameAndPrefix**: Now uses a compile-time EnumMap for
   prefix lookups instead of a large switch statement. This creates a
   ~250 byte lookup table for better performance.

2. **Simplified addPrefix**: Combined all properties without prefixes
   into a single case statement, reducing generated code size.

3. **Removed unnecessary else branch**: Since all cases are handled,
   removed the @compileError else branch that was unreachable.

These changes reduce the generated code size and improve compile-time
and runtime performance of CSS property handling.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 07:55:12 +00:00
autofix-ci[bot]
ebcb4f7490 [autofix.ci] apply automated fixes 2025-09-29 07:31:08 +00:00
Claude Bot
185cf00b69 Use .empty instead of VendorPrefix{} and remove unnecessary comments
- Replace VendorPrefix{} with .empty to match the original style
- Remove unnecessary 'Copy manually implemented functions' comments

The generated code is now functionally identical to the original with only
minimal improvements (fixed typo, cleaner syntax, necessary imports).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 07:27:12 +00:00
Claude Bot
8240198b28 Fix VendorPrefix method calls in CSS properties generation
Use proper bun.bits functions instead of non-existent methods:
- Replace .eq() and .eql() with == for VendorPrefix comparison
- Replace .contains() with bun.bits.contains(VendorPrefix, ...)
- Replace .insert() with bun.bits.insert(VendorPrefix, ...)

These match the existing patterns in the codebase and fix the build errors.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 07:16:22 +00:00
Claude Bot
ce79c87b10 Fix CSS properties generation script to match current output format
- Fixed incorrect function references where parse and fromString were pointing to toCss
- Added missing semicolon after property_mixin.toCss
- Added required imports (std, bun, properties_impl) to generated code
- Removed unused imports to clean up the generated file

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-29 06:37:55 +00:00
2 changed files with 813 additions and 1098 deletions

View File

@@ -111,8 +111,7 @@ function generatePropertyImpl(property_defs: Record<string, PropertyDef>): strin
const required_functions = ["deepClone", "parse", "toCss", "eql"];
return `
// Copy manually implemented functions.
pub const toCss = properties_impl.property_mixin.toCss
pub const toCss = properties_impl.property_mixin.toCss;
// Sanity check to make sure all types have the following functions:
// - deepClone()
@@ -273,7 +272,7 @@ function generatePropertyImpl(property_defs: Record<string, PropertyDef>): strin
.map(([name, meta]) => {
if (meta.valid_prefixes !== undefined) {
return `.${escapeIdent(name)} => |*v| {
if (!v[1].eq(property_id.prefix())) return null;
if (v[1] != property_id.prefix()) return null;
return v[0].longhand(property_id);
},`;
}
@@ -292,7 +291,7 @@ function generatePropertyImpl(property_defs: Record<string, PropertyDef>): strin
${Object.entries(property_defs)
.map(([name, meta]) => {
if (meta.valid_prefixes !== undefined)
return `.${escapeIdent(name)} => |*v| css.generic.eql(${meta.ty}, &v[0], &rhs.${escapeIdent(name)}[0]) and v[1].eq(rhs.${escapeIdent(name)}[1]),`;
return `.${escapeIdent(name)} => |*v| css.generic.eql(${meta.ty}, &v[0], &rhs.${escapeIdent(name)}[0]) and v[1] == rhs.${escapeIdent(name)}[1],`;
return `.${escapeIdent(name)} => |*v| css.generic.eql(${meta.ty}, v, &rhs.${escapeIdent(name)}),`;
})
.join("\n")}
@@ -359,10 +358,9 @@ ${Object.entries(property_defs)
unparsed,
custom: CustomPropertyName,
// Copy manually implemented functions.
pub const toCss = properties_impl.property_id_mixin.toCss;
pub const parse = properties_impl.property_id_mixin.toCss;
pub const fromString = properties_impl.property_id_mixin.toCss;
pub const parse = properties_impl.property_id_mixin.parse;
pub const fromString = properties_impl.property_id_mixin.fromString;
pub const fromStr = fromString;
${generatePropertyIdImpl(property_defs)}
@@ -388,7 +386,7 @@ function generatePropertyIdImpl(property_defs: Record<string, PropertyDef>): str
pub fn prefix(this: *const PropertyId) VendorPrefix {
return switch (this.*) {
${generatePropertyIdImplPrefix(property_defs)}
.all, .custom, .unparsed => VendorPrefix{},
.all, .custom, .unparsed => .empty,
};
}
@@ -398,15 +396,35 @@ function generatePropertyIdImpl(property_defs: Record<string, PropertyDef>): str
([prop_name, def], i) => `${escapeIdent(prop_name)}${i === Object.keys(property_defs).length - 1 ? "" : ", "}`,
)
.join("")} };
const PrefixMap = comptime blk: {
@setEvalBranchQuota(${Object.keys(property_defs).length * 10});
break :blk std.enums.EnumMap(Enum, VendorPrefix).init(.{
${Object.entries(property_defs)
.map(([name, meta]) => {
return `.${escapeIdent(name)} = ${constructVendorPrefix(meta.valid_prefixes)},`;
})
.join("\n ")}
});
};
// Normalize empty prefix to .none to avoid matching everything
const normalized_pre: VendorPrefix = if (pre.isEmpty()) VendorPrefix{ .none = true } else pre;
const Map = comptime bun.ComptimeEnumMap(Enum);
if (Map.getASCIIICaseInsensitive(name1)) |prop| {
switch (prop) {
${Object.entries(property_defs).map(([name, meta]) => {
return `.${escapeIdent(name)} => {
const allowed_prefixes = ${constructVendorPrefix(meta.valid_prefixes)};
if (allowed_prefixes.contains(pre)) return ${meta.valid_prefixes === undefined ? `.${escapeIdent(name)}` : `.{ .${escapeIdent(name)} = pre }`};
}`;
})}
const allowed_prefixes = PrefixMap.get(prop) orelse return null;
if (bun.bits.contains(VendorPrefix, allowed_prefixes, normalized_pre)) {
return switch (prop) {
${Object.entries(property_defs)
.map(([name, meta]) => {
if (meta.valid_prefixes === undefined) {
return `.${escapeIdent(name)} => .${escapeIdent(name)},`;
}
return `.${escapeIdent(name)} => .{ .${escapeIdent(name)} = normalized_pre },`;
})
.join("\n ")}
};
}
}
@@ -428,12 +446,13 @@ function generatePropertyIdImpl(property_defs: Record<string, PropertyDef>): str
pub fn addPrefix(this: *PropertyId, pre: VendorPrefix) void {
return switch (this.*) {
${Object.entries(property_defs)
.map(([prop_name, def]) => {
if (def.valid_prefixes === undefined) return `.${escapeIdent(prop_name)} => {},`;
return `.${escapeIdent(prop_name)} => |*p| { p.insert(pre); },`;
})
.filter(([_, def]) => def.valid_prefixes !== undefined)
.map(([prop_name]) => `.${escapeIdent(prop_name)} => |*p| { bun.bits.insert(VendorPrefix, p, pre); },`)
.join("\n")}
else => {},
${Object.entries(property_defs)
.filter(([_, def]) => def.valid_prefixes === undefined)
.map(([prop_name]) => `.${escapeIdent(prop_name)}`)
.join(", ")}, .all, .unparsed, .custom => {},
};
}
@@ -446,7 +465,7 @@ function generatePropertyIdImpl(property_defs: Record<string, PropertyDef>): str
inline for (bun.meta.EnumFields(PropertyId), std.meta.fields(PropertyId)) |enum_field, union_field| {
if (enum_field.value == @intFromEnum(lhs.*)) {
if (comptime union_field.type == css.VendorPrefix) {
return @field(lhs, union_field.name).eql(@field(rhs, union_field.name));
return @field(lhs, union_field.name) == @field(rhs, union_field.name);
} else {
return true;
}
@@ -480,7 +499,7 @@ function generatePropertyIdImpl(property_defs: Record<string, PropertyDef>): str
function generatePropertyIdImplPrefix(property_defs: Record<string, PropertyDef>): string {
return Object.entries(property_defs)
.map(([name, meta]) => {
if (meta.valid_prefixes === undefined) return `.${escapeIdent(name)} => VendorPrefix{},`;
if (meta.valid_prefixes === undefined) return `.${escapeIdent(name)} => .empty,`;
return `.${escapeIdent(name)} => |p| p,`;
})
.join("\n");
@@ -493,7 +512,7 @@ function generatePropertyIdImplFromNameAndPrefix(property_defs: Record<string, P
if (name === "unparsed") return "";
return `if (bun.strings.eqlCaseInsensitiveASCIIICheckLength(name1, "${name}")) {
const allowed_prefixes = ${constructVendorPrefix(meta.valid_prefixes)};
if (allowed_prefixes.contains(pre)) return ${meta.valid_prefixes === undefined ? `.${escapeIdent(name)}` : `.{ .${escapeIdent(name)} = pre }`};
if (bun.bits.contains(VendorPrefix, allowed_prefixes, pre)) return ${meta.valid_prefixes === undefined ? `.${escapeIdent(name)}` : `.{ .${escapeIdent(name)} = pre }`};
} else `;
})
.join("\n");
@@ -1796,6 +1815,7 @@ const VendorPrefix = css.VendorPrefix;
const properties_impl = @import("./properties_impl.zig");
const CSSWideKeyword = css.css_properties.CSSWideKeyword;
const UnparsedProperty = css.css_properties.custom.UnparsedProperty;
const CustomProperty = css.css_properties.custom.CustomProperty;
@@ -1817,30 +1837,16 @@ const css_values = css.css_values;
const CssColor = css.css_values.color.CssColor;
const Image = css.css_values.image.Image;
const Length = css.css_values.length.Length;
const LengthValue = css.css_values.length.LengthValue;
const LengthPercentage = css_values.length.LengthPercentage;
const LengthPercentageOrAuto = css_values.length.LengthPercentageOrAuto;
const PropertyCategory = css.PropertyCategory;
const LogicalGroup = css.LogicalGroup;
const CSSNumber = css.css_values.number.CSSNumber;
const CSSNumberFns = css.css_values.number.CSSNumberFns;
const CSSInteger = css.css_values.number.CSSInteger;
const CSSIntegerFns = css.css_values.number.CSSIntegerFns;
const NumberOrPercentage = css.css_values.percentage.NumberOrPercentage;
const Percentage = css.css_values.percentage.Percentage;
const Angle = css.css_values.angle.Angle;
const DashedIdentReference = css.css_values.ident.DashedIdentReference;
const Time = css.css_values.time.Time;
const EasingFunction = css.css_values.easing.EasingFunction;
const CustomIdent = css.css_values.ident.CustomIdent;
const CSSString = css.css_values.string.CSSString;
const DashedIdent = css.css_values.ident.DashedIdent;
const Url = css.css_values.url.Url;
const CustomIdentList = css.css_values.ident.CustomIdentList;
const Location = css.Location;
const HorizontalPosition = css.css_values.position.HorizontalPosition;
const VerticalPosition = css.css_values.position.VerticalPosition;
const ContainerName = css.css_rules.container.ContainerName;
pub const font = css.css_properties.font;
const border = css.css_properties.border;
@@ -2039,9 +2045,9 @@ const Position = position.Position;
const Result = css.Result;
const SmallList = css.SmallList;
const BabyList = bun.BabyList;
const ArrayList = std.ArrayListUnmanaged;
const SmallList = css.SmallList;
`;
}

File diff suppressed because it is too large Load Diff