Bug 12159 - Most of CSSComputedStyleDeclaration, cssparser.cpp, cssstyleselector.cpp should be autogenerated
Summary: Most of CSSComputedStyleDeclaration, cssparser.cpp, cssstyleselector.cpp shou...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: CSS (show other bugs)
Version: 420+
Hardware: Mac OS X 10.4
: P2 Normal
Assignee: Nobody
URL:
Keywords:
: 15427 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-01-08 00:56 PST by Eric Seidel (no email)
Modified: 2009-03-05 16:40 PST (History)
5 users (show)

See Also:


Attachments
Move enum mapping into a separate file (214.89 KB, patch)
2007-10-14 08:11 PDT, Alexey Proskuryakov
darin: review-
Details | Formatted Diff | Diff
updated patch (214.99 KB, patch)
2007-10-16 23:48 PDT, Alexey Proskuryakov
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Seidel (no email) 2007-01-08 00:56:55 PST
Most of CSSComputedStyleDeclaration, cssparser.cpp, cssstyleselector.cpp should be autogenerated

Hyatt and I were just talking about this over IRC.... most of the CSS code is pretty repetitive (and as a result ugly).  It's full of copy/paste and macro code which is either prone to errors or difficult to debug.  It would be best to replace most of this CSS code with autogenerated code, similar to what was done with the JS bindings system.
Comment 1 Alexey Proskuryakov 2007-01-08 01:42:40 PST
Is autogeneration the only way to improve CSS code? Maybe it's just me, but I find autogenerated code to be harder to read and debug than any other kind of code.
Comment 2 mitz 2007-10-08 10:40:58 PDT
*** Bug 15427 has been marked as a duplicate of this bug. ***
Comment 3 Alexey Proskuryakov 2007-10-08 11:07:37 PDT
I'd be happy to discuss specific examples of code that is suggested for auto-generation, hoping to suggest alternatives, e.g. template-based. If there aren't any, then auto-generation may be a great answer (as it is for IDL-generated bindings).
Comment 4 Alexey Proskuryakov 2007-10-09 12:48:33 PDT
I think that a lot of ugly code can be eliminated by moving enum mapping to CSSPrimitiveValue. E.g.

            switch (style->resize()) {
                case RESIZE_BOTH:
                    return new CSSPrimitiveValue(CSS_VAL_BOTH);
                case RESIZE_HORIZONTAL:
                    return new CSSPrimitiveValue(CSS_VAL_HORIZONTAL);
                case RESIZE_VERTICAL:
                    return new CSSPrimitiveValue(CSS_VAL_VERTICAL);
                case RESIZE_NONE:
                    return new CSSPrimitiveValue(CSS_VAL_NONE);
            }

could hopefully become

            return new CSSPrimitiveValue(style->resize());

Comment 5 Eric Seidel (no email) 2007-10-09 13:28:03 PDT
(In reply to comment #4)
> I think that a lot of ugly code can be eliminated by moving enum mapping to
> CSSPrimitiveValue. E.g.

That's an interesting idea, but that would mean creating 100 different constructors, no?  Or would you use some sort of template magic to do such?  (If so, please provide an example.)
Comment 6 Alexey Proskuryakov 2007-10-09 21:39:29 PDT
(In reply to comment #5)
> That's an interesting idea, but that would mean creating 100 different
> constructors, no?

Yes, I don't see how to avoid that yet. Still, should save quite a few lines of code.

I'm going to actually work on some patches along these lines.
Comment 7 Alexey Proskuryakov 2007-10-14 08:11:47 PDT
Created attachment 16667 [details]
Move enum mapping into a separate file

This patch is IMHO helpful regardless of whether we decide to auto-generate any more code.

The CSSComputedStyleDeclaration part is pretty straightforward. In CSSStyleSelector, there was some error checking I don't quite understand, especially because not all cases have it. I might have removed something important, or kept something unnecessary.

-        if (!primitiveValue || !primitiveValue->getIdent())
-            return;
...
-    if (!value->isPrimitiveValue()) return;

It seems that these are guaranteed by the parser. Similarly, some checks for unexpected ident values may have changed, but it doesn't seem that they actually come into play unless memory is overwritten.
Comment 8 Darin Adler 2007-10-15 07:43:53 PDT
Comment on attachment 16667 [details]
Move enum mapping into a separate file

+            ASSERT(boxAlign != BJUSTIFY);
+            if (boxAlign == BJUSTIFY)
+                return 0;

+            ASSERT(pageBreak != PBALWAYS);
+            if (pageBreak == PBALWAYS)
+                return 0;

The checking here seems unnecessary. I think we can just omit it.

Do we have test cases that cover all the different length types and property values?

-        CSSPrimitiveValue* val = new CSSPrimitiveValue(pair);
+        CSSPrimitiveValue* val = new CSSPrimitiveValue(PassRefPtr<Pair>(pair));

I think that needing to do this is quite unfortunate. Because of this, I'm not happy with the template conversion technique. Can we switch to a simpler technique that doesn't involve templates?

We could just put all the enums into a separate header file and use plain old overloading.

I otherwise think this is cool, and a great direction.
Comment 9 Alexey Proskuryakov 2007-10-16 00:48:57 PDT
(In reply to comment #8)

> Can we switch to a simpler technique that doesn't involve templates?

  I thought plain overloading would be unsafe, because missing constructors wouldn't be detected - there are already constructors that take int and unsigned.

  One option I thought of (and actually started to implement) was to use a separate construction method, something like

    template<typename T> static CSSPrimitiveValue* fromEnum(T);

  But that looked even worse than having to explicitly construct PassRefPtr in a few places.
Comment 10 Darin Adler 2007-10-16 07:42:09 PDT
(In reply to comment #9)
> (In reply to comment #8)
> 
> > Can we switch to a simpler technique that doesn't involve templates?
> 
>   I thought plain overloading would be unsafe, because missing constructors
> wouldn't be detected - there are already constructors that take int and
> unsigned.

Wow, that's a good point. I had overlooked that.

Maybe we should go back to your original patch, but I have some other ideas worth considering:

    1) Change the identifier values into an enum, and get rid of the int constructor. Probably straightforward to do.
    2) For colors, change the constructor to either use a wrapper (WebCore::Color has an unwanted "invalid" state, and is slightly less efficient than a plain RGB value, but it might still be OK) or a named constructor like fromColor.

I don't feel super-strongly about the color one, but I do think that the "int for identifier" thing is weak and should be changed.
Comment 11 Darin Adler 2007-10-16 07:44:08 PDT
3) Use the simple "extra parameter" technique used in RetainPtr's Adopt constructors. An initial parameter with a type that's significant, but not a value.
Comment 12 Alexey Proskuryakov 2007-10-16 09:36:07 PDT
One thing that I like about the template-based solution is that there is no need to add dozens of constructors to CSSPrimitiveValue.h. Not that there would be anything inherently wrong with that, but it looks somewhat ugly to me.
Comment 13 Darin Adler 2007-10-16 10:20:30 PDT
(In reply to comment #12)
> One thing that I like about the template-based solution is that there is no
> need to add dozens of constructors to CSSPrimitiveValue.h. Not that there would
> be anything inherently wrong with that, but it looks somewhat ugly to me.

I think it's clearer to have the declarations, even though it's a little uglier.
Comment 14 Alexey Proskuryakov 2007-10-16 23:48:01 PDT
Created attachment 16692 [details]
updated patch

(In reply to comment #8)

> The checking here seems unnecessary. I think we can just omit it.

Done.

> Do we have test cases that cover all the different length types and property
> values?

Hmm, I think the tests in css1/ and css2.1/ cover this.

> I think that needing to do this is quite unfortunate. Because of this, I'm not
> happy with the template conversion technique. Can we switch to a simpler
> technique that doesn't involve templates?

Attached is another attempt to save the template technique :)
Comment 15 Darin Adler 2007-10-17 21:04:42 PDT
Comment on attachment 16692 [details]
updated patch

OK. I can live with this. r=me
Comment 16 Alexey Proskuryakov 2007-10-18 01:50:46 PDT
Comment on attachment 16692 [details]
updated patch

Patch committed in revision 26742, clearing the review flag to keep the bug open.
Comment 17 Eric Seidel (no email) 2007-10-18 01:58:43 PDT
We should probably just open a new bug and mark this as a "depends on".  Generally one commit per bug.
Comment 18 Eric Seidel (no email) 2009-03-05 16:40:09 PST
This was done a while ago.