From 01dc2a8cf44fb90615f91674181405e8d6824386 Mon Sep 17 00:00:00 2001 From: Martin Stjernholm <mast@lysator.liu.se> Date: Wed, 26 Jan 2011 22:07:14 +0100 Subject: [PATCH] Added support for typed constants in the doc extractor. The type can either be given explicitly between the "constant" keyword and the identifier, or it can be determined from the constant expression if it's specified and is a plain literal. Note: This makes the parsing of constant declarations somewhat more strict, which can cause errors in existing AutoDoc markup. This change makes the constant declarations in the GSSAPI module correct. --- .../Tools.pmod/AutoDoc.pmod/PikeObjects.pmod | 4 ++ .../Tools.pmod/AutoDoc.pmod/PikeParser.pike | 40 +++++++++++++++++++ refdoc/keywords.txt | 9 +++++ refdoc/presentation/make_html.pike | 2 + refdoc/xml.txt | 3 +- 5 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lib/modules/Tools.pmod/AutoDoc.pmod/PikeObjects.pmod b/lib/modules/Tools.pmod/AutoDoc.pmod/PikeObjects.pmod index fc0fb121ad..106ef7b961 100644 --- a/lib/modules/Tools.pmod/AutoDoc.pmod/PikeObjects.pmod +++ b/lib/modules/Tools.pmod/AutoDoc.pmod/PikeObjects.pmod @@ -821,11 +821,15 @@ class Constant { //! constant objtype = "constant"; + //! The type of the constant, if known. + Type type; + //! Typedef @[Type] if it is a typedef. Type typedefType = 0; string xml() { return standardStart() + standardTags() + + (type ? xmltag ("type", type->xml()) : "") + (typedefType ? xmltag("typevalue", typedefType->xml()) : "") + standardEnd(); } diff --git a/lib/modules/Tools.pmod/AutoDoc.pmod/PikeParser.pike b/lib/modules/Tools.pmod/AutoDoc.pmod/PikeParser.pike index 00c16e1252..e477220a25 100644 --- a/lib/modules/Tools.pmod/AutoDoc.pmod/PikeParser.pike +++ b/lib/modules/Tools.pmod/AutoDoc.pmod/PikeParser.pike @@ -680,6 +680,33 @@ void|string parseLiteral() { return 0; } +Type literalType (string literal) +//! Returns the type of a literal. Currently only recognizes the top +//! level type. Currently does not thoroughly check that the literal +//! is syntactically valid. +{ + if (sizeof (literal)) + switch (literal[0]) { + case '\'': return IntType(); // Character constant. + case '"': return StringType(); + case '(': + if (sizeof (literal) > 1) + switch (literal[1]) { + case '{': return ArrayType(); + case '[': return MappingType(); + case '<': return MultisetType(); + } + break; + default: + if (sscanf (literal, "%*D%*c") == 1) + return IntType(); + if (sscanf (literal, "%*f%*c") == 1) + return FloatType(); + } + // Unrecognized format. Add an option to trig a parse error instead? + return 0; +} + //! Expect a literal constant. //! //! @seealso @@ -731,9 +758,22 @@ PikeObject|array(PikeObject) parseDecl(mapping|void args) { c->position = position; c->modifiers = modifiers; readToken(); + int save_pos = tokenPtr; + mixed err = catch (c->type = parseOrType()); + if (err && (!objectp (err) || !err->is_pike_parse_error)) + throw (err); + if (err || (<"=", ";", EOF>)[peekToken()]) { + c->type = 0; + tokenPtr = save_pos; + } c->name = eatIdentifier(); if (peekToken() == "=") { eat("="); + if (string l = parseLiteral()) + // It's intentional that literalType doesn't return too + // specific types for integers, i.e. it's int instead of e.g. + // int(4711..4711). + c->type = literalType (l); // TODO: parse the expression ??? // added parsing only of types... // a constant value will just be ignored. diff --git a/refdoc/keywords.txt b/refdoc/keywords.txt index 955c939476..109cf6f4d6 100644 --- a/refdoc/keywords.txt +++ b/refdoc/keywords.txt @@ -83,6 +83,12 @@ Description: Declare a Pike entity and state that the current 2. All @decl's in the block are methods with the same name as that method. (look at the last example below) + + The rest of the line after @decl should follow real pike + syntax, but the ending semicolon is optional. There are + some differences though, notably it allows a type to be + specified for constants. + Arguments: <declaration> Where: <declaration> is a valid Pike declaration. A trailing @@ -101,6 +107,9 @@ Examples: //! This is how to document a "polymorph" function. float|int cube(float|int x) { /* body */ } + //! @decl constant int bitmask + //! A constant which has a public type but private value. + _______________________________________________________________________________ Keyword: @endclass diff --git a/refdoc/presentation/make_html.pike b/refdoc/presentation/make_html.pike index 5efbe1b4fe..ef8bf0f8af 100644 --- a/refdoc/presentation/make_html.pike +++ b/refdoc/presentation/make_html.pike @@ -1100,6 +1100,8 @@ string parse_not_doc(Node n) { case "constant": if(const++) ret += "<br />\n"; ret += "<tt>constant "; + if (Node type = c->get_first_element ("type")) + ret += parse_type (get_first_element (type), "constant") + " "; ret += c->get_attributes()->class_path; ret += "<font color='#F000F0'>" + c->get_attributes()->name + "</font>"; cc = c->get_first_element("typevalue"); diff --git a/refdoc/xml.txt b/refdoc/xml.txt index 409c12cb58..6cd0899a29 100644 --- a/refdoc/xml.txt +++ b/refdoc/xml.txt @@ -200,7 +200,8 @@ entities: </class> <constant> - Only has a name. The element is empty (or has a <source-position> child.) + Has a name attribute. Contains optional <type> and + <source-position> child elements. <enum> Works as a container. Has a <doc> child element with the documentation of -- GitLab