Fixes bug 529040, bug 540513, and bug 546096.
* @param s a string
*/
public void write_string (string s) {
- stream.printf ("%s", s);
+ stream.puts (s);
_bol = false;
}
indent--;
write_indent ();
- stream.printf ("}");
+ stream.putc ('}');
}
/**
*/
public void write_comment (string text) {
write_indent ();
- stream.printf ("/*");
+ stream.puts ("/*");
bool first = true;
/* separate declaration due to missing memory management in foreach statements */
} else {
first = false;
}
- stream.printf ("%s", line);
+
+ var lineparts = line.split ("*/");
+
+ for (int i = 0; lineparts[i] != null; i++) {
+ stream.puts (lineparts[i]);
+ if (lineparts[i+1] != null) {
+ stream.puts ("* /");
+ }
+ }
}
- stream.printf ("*/");
+ stream.puts ("*/");
write_newline ();
}
}
source_type_member_definition.append (cfunc);
}
-
- CCodeComment comment = null;
- if (source_file.comment != null) {
- comment = new CCodeComment (source_file.comment);
- }
var writer = new CCodeWriter (source_file.get_csource_filename ());
if (!writer.open ()) {
return;
}
writer.line_directives = context.debug;
- if (comment != null) {
- comment.write (writer);
+
+ var comments = source_file.get_comments();
+ if (comments != null) {
+ foreach (Comment comment in comments) {
+ var ccomment = new CCodeComment (comment.content);
+ ccomment.write (writer);
+ }
}
+
writer.write_newline ();
source_declarations.include_directives.write (writer);
writer.write_newline ();
cenum.add_value (new CCodeEnumValue (ev.get_cname (), (CCodeExpression) ev.value.ccodenode));
}
}
-
- if (en.source_reference.comment != null) {
- decl_space.add_type_definition (new CCodeComment (en.source_reference.comment));
- }
decl_space.add_type_definition (cenum);
decl_space.add_type_definition (new CCodeNewline ());
if (stmt.error) {
continue;
}
-
- var src = stmt.source_reference;
- if (src != null && src.comment != null) {
- cblock.add_statement (new CCodeComment (src.comment));
- }
if (stmt.ccodenode is CCodeFragment) {
foreach (CCodeNode cstmt in ((CCodeFragment) stmt.ccodenode).get_children ()) {
}
var ctypedef = new CCodeTypeDefinition (return_type_cname, cfundecl);
-
- if (d.source_reference != null && d.source_reference.comment != null) {
- decl_space.add_type_definition (new CCodeComment (d.source_reference.comment));
- }
decl_space.add_type_definition (ctypedef);
}
}
if (!m.coroutine) {
- if (m.source_reference != null && m.source_reference.comment != null) {
- source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
- }
source_type_member_definition.append (function);
}
vfunc.block = vblock;
- if (m.is_abstract && m.source_reference != null && m.source_reference.comment != null) {
- source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
- }
source_type_member_definition.append (vfunc);
}
decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (st.get_cname ()), new CCodeVariableDeclarator (st.get_cname ())));
- if (st.source_reference.comment != null) {
- decl_space.add_type_definition (new CCodeComment (st.source_reference.comment));
- }
decl_space.add_type_definition (instance_struct);
var function = new CCodeFunction (st.get_dup_function (), st.get_cname () + "*");
}
}
- if (edomain.source_reference.comment != null) {
- decl_space.add_type_definition (new CCodeComment (edomain.source_reference.comment));
- }
decl_space.add_type_definition (cenum);
string quark_fun_name = edomain.get_lower_case_cprefix () + "quark";
function.block = cblock;
- if (c.source_reference.comment != null) {
- source_type_member_definition.append (new CCodeComment (c.source_reference.comment));
- }
source_type_member_definition.append (function);
} else if (c.binding == MemberBinding.CLASS) {
// class constructor
}
}
- if (cl.source_reference.comment != null) {
- decl_space.add_type_definition (new CCodeComment (cl.source_reference.comment));
- }
if (!cl.is_compact || cl.base_class == null) {
// derived compact classes do not have a struct
decl_space.add_type_definition (instance_struct);
}
}
- if (iface.source_reference.comment != null) {
- decl_space.add_type_definition (new CCodeComment (iface.source_reference.comment));
- }
decl_space.add_type_definition (type_struct);
var type_fun = create_interface_register_function (iface);
valacodenode.vala \
valacodevisitor.vala \
valacodewriter.vala \
+ valacomment.vala \
valaconditionalexpression.vala \
valaconstant.vala \
valaconstructor.vala \
*
* @param name type name
* @param source reference to source code
+ * @param comment class documentation
* @return newly created class
*/
- public Class (string name, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public Class (string name, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
}
/**
--- /dev/null
+/* valacomment.vala
+ *
+ * Copyright (C) 2008-2009 Florian Brosch
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Florian Brosch <flo.brosch@gmail.com>
+ */
+
+using GLib;
+
+/**
+ * A documentation comment used by valadoc
+ */
+public class Vala.Comment {
+ public Comment (string comment, SourceReference _source_reference) {
+ source_reference = _source_reference;
+ content = comment;
+ }
+
+ /**
+ * The text describing the referenced source code.
+ */
+ public string content { set; get; }
+
+ /**
+ * References the location in the source file where this code node has
+ * been written.
+ */
+ public SourceReference source_reference { get; set; }
+}
+
* @param source_reference reference to source code
* @return newly created constant
*/
- public Constant (string name, DataType type_reference, Expression? initializer, SourceReference? source_reference) {
- base (name, source_reference);
+ public Constant (string name, DataType type_reference, Expression? initializer, SourceReference? source_reference, Comment? comment = null) {
+ base (name, source_reference, comment);
this.type_reference = type_reference;
this.initializer = initializer;
}
* @param source_reference reference to source code
* @return newly created method
*/
- public CreationMethod (string? class_name, string? name, SourceReference? source_reference = null) {
- base (name, new VoidType (), source_reference);
+ public CreationMethod (string? class_name, string? name, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, new VoidType (), source_reference, comment);
this.class_name = class_name;
carray_length_parameter_position = -3;
* @param source reference to source code
* @return newly created delegate
*/
- public Delegate (string? name, DataType return_type, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public Delegate (string? name, DataType return_type, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
this.return_type = return_type;
// error is -1 (right of user_data)
private string cname;
static int dynamic_method_id;
- public DynamicMethod (DataType dynamic_type, string name, DataType return_type, SourceReference? source_reference = null) {
- base (name, return_type, source_reference);
+ public DynamicMethod (DataType dynamic_type, string name, DataType return_type, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, return_type, source_reference, comment);
this.dynamic_type = dynamic_type;
}
public class Vala.DynamicProperty : Property {
public DataType dynamic_type { get; set; }
- public DynamicProperty (DataType dynamic_type, string name, SourceReference? source_reference = null) {
- base (name, null, null, null, source_reference);
+ public DynamicProperty (DataType dynamic_type, string name, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, null, null, null, source_reference, comment);
this.dynamic_type = dynamic_type;
}
public Expression handler { get; set; }
- public DynamicSignal (DataType dynamic_type, string name, DataType return_type, SourceReference? source_reference = null) {
- base (name, return_type, source_reference);
+ public DynamicSignal (DataType dynamic_type, string name, DataType return_type, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, return_type, source_reference, comment);
this.dynamic_type = dynamic_type;
}
* @param source_reference reference to source code
* @return newly created enum
*/
- public Enum (string name, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public Enum (string name, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
}
/**
*/
public Expression value { get; set; }
+ public Comment comment { get; set; }
+
private string cname;
/**
* @param name enum value name
* @return newly created enum value
*/
- public EnumValue (string name, SourceReference? source_reference = null) {
+ public EnumValue (string name, SourceReference? source_reference = null, Comment? comment = null) {
base (name, source_reference);
+ this.comment = comment;
}
/**
* @param value numerical representation
* @return newly created enum value
*/
- public EnumValue.with_value (string name, Expression value, SourceReference? source_reference = null) {
- this (name, source_reference);
+ public EnumValue.with_value (string name, Expression value, SourceReference? source_reference = null, Comment? comment = null) {
+ this (name, source_reference, comment);
this.value = value;
}
* @param name enum value name
* @return newly created enum value
*/
- public ErrorCode (string name, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public ErrorCode (string name, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
}
/**
* @param source_reference reference to source code
* @return newly created error domain
*/
- public ErrorDomain (string name, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public ErrorDomain (string name, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
}
/**
* @param source reference to source code
* @return newly created field
*/
- public Field (string name, DataType field_type, Expression? initializer, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public Field (string name, DataType field_type, Expression? initializer, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
this.field_type = field_type;
this.initializer = initializer;
}
// number of tokens in buffer
int size;
- string comment;
+ Comment comment;
string class_name;
return new SourceReference (scanner.source_file, begin.line, begin.column, tokens[last_index].end.line, tokens[last_index].end.column);
}
- SourceReference get_src_com (SourceLocation begin) {
- int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
-
- var src = new SourceReference.with_comment (scanner.source_file, begin.line, begin.column, tokens[last_index].end.line, tokens[last_index].end.column, comment);
- comment = null;
- return src;
- }
-
SourceReference get_current_src () {
return new SourceReference (scanner.source_file, tokens[index].begin.line, tokens[index].begin.column, tokens[index].end.line, tokens[index].end.column);
}
expect (TokenType.EOL);
}
- stmt = new EmptyStatement (get_src_com (begin));
+ stmt = new EmptyStatement (get_src (begin));
break;
comment = scanner.pop_comment ();
- var block = new Block (get_src_com (get_location ()));
+ var block = new Block (get_src (get_location ()));
block.add_statement (parse_embedded_statement_without_block ());
return block;
Block parse_block () throws ParseError {
var begin = get_location ();
expect (TokenType.INDENT);
- var block = new Block (get_src_com (begin));
+ var block = new Block (get_src (begin));
parse_statements (block);
if (!accept (TokenType.DEDENT)) {
// only report error if it's not a secondary error
accept (TokenType.SEMICOLON);
expect_terminator ();
- return new EmptyStatement (get_src_com (begin));
+ return new EmptyStatement (get_src (begin));
}
void add_local_var_variable (Block block, string id) throws ParseError {
if (accept (TokenType.ASSIGN)) {
initializer = parse_expression ();
}
- return new LocalVariable (variable_type, id, initializer, get_src_com (begin));
+ return new LocalVariable (variable_type, id, initializer, get_src (begin));
}
Statement parse_expression_statement () throws ParseError {
expect_terminator ();
}
- return new ExpressionStatement (expr, get_src_com (begin));
+ return new ExpressionStatement (expr, get_src (begin));
}
Expression parse_statement_expression () throws ParseError {
accept (TokenType.EOL);
}
- var src = get_src_com (begin);
+ var src = get_src (begin);
var true_stmt = parse_embedded_statement ();
Block false_stmt = null;
if (accept (TokenType.ELSE)) {
expect (TokenType.EOL);
- var stmt = new SwitchStatement (condition, get_src_com (begin));
+ var stmt = new SwitchStatement (condition, get_src (begin));
expect (TokenType.INDENT);
while (current () != TokenType.DEDENT) {
- var section = new SwitchSection (get_src_com (begin));
+ var section = new SwitchSection (get_src (begin));
if (accept (TokenType.WHEN)) {
do {
- section.add_label (new SwitchLabel (parse_expression (), get_src_com (begin)));
+ section.add_label (new SwitchLabel (parse_expression (), get_src (begin)));
}
while (accept (TokenType.COMMA));
} else {
expect (TokenType.DEFAULT);
- section.add_label (new SwitchLabel.with_default (get_src_com (begin)));
+ section.add_label (new SwitchLabel.with_default (get_src (begin)));
}
if (!accept (TokenType.EOL)) {
parse_statements (section);
/* add break statement for each block */
- var break_stmt = new BreakStatement (get_src_com (begin));
+ var break_stmt = new BreakStatement (get_src (begin));
section.add_statement (break_stmt);
stmt.add_section (section);
}
var body = parse_embedded_statement ();
- return new WhileStatement (condition, body, get_src_com (begin));
+ return new WhileStatement (condition, body, get_src (begin));
}
Statement parse_do_statement () throws ParseError {
expect_terminator ();
- return new DoStatement (body, condition, get_src_com (begin));
+ return new DoStatement (body, condition, get_src (begin));
}
expect (TokenType.DO);
}
- var src = get_src_com (begin);
+ var src = get_src (begin);
var body = parse_embedded_statement ();
var stmt = new ForStatement (condition, body, src);
if (!accept (TokenType.EOL)) {
expect (TokenType.DO);
}
- var src = get_src_com (begin);
+ var src = get_src (begin);
var body = parse_embedded_statement ();
return new ForeachStatement (type, id, collection, body, src);
}
var begin = get_location ();
expect (TokenType.BREAK);
expect_terminator ();
- return new BreakStatement (get_src_com (begin));
+ return new BreakStatement (get_src (begin));
}
Statement parse_continue_statement () throws ParseError {
var begin = get_location ();
expect (TokenType.CONTINUE);
expect_terminator ();
- return new ContinueStatement (get_src_com (begin));
+ return new ContinueStatement (get_src (begin));
}
Statement parse_return_statement () throws ParseError {
expr = parse_expression ();
}
expect_terminator ();
- return new ReturnStatement (expr, get_src_com (begin));
+ return new ReturnStatement (expr, get_src (begin));
}
Statement parse_yield_statement () throws ParseError {
expect (TokenType.RAISE);
var expr = parse_expression ();
expect_terminator ();
- return new ThrowStatement (expr, get_src_com (begin));
+ return new ThrowStatement (expr, get_src (begin));
}
Statement parse_try_statement () throws ParseError {
} else {
finally_clause = parse_finally_clause ();
}
- var stmt = new TryStatement (try_block, finally_clause, get_src_com (begin));
+ var stmt = new TryStatement (try_block, finally_clause, get_src (begin));
foreach (CatchClause clause in catch_clauses) {
stmt.add_catch_clause (clause);
}
var expr = parse_expression ();
expect (TokenType.CLOSE_PARENS);
var stmt = parse_embedded_statement ();
- return new LockStatement (expr, stmt, get_src_com (begin));
+ return new LockStatement (expr, stmt, get_src (begin));
}
Statement parse_delete_statement () throws ParseError {
expect (TokenType.DELETE);
var expr = parse_expression ();
expect_terminator ();
- return new DeleteStatement (expr, get_src_com (begin));
+ return new DeleteStatement (expr, get_src (begin));
}
Gee.List<Attribute>? parse_attributes () throws ParseError {
var begin = get_location ();
expect (TokenType.NAMESPACE);
var sym = parse_symbol_name ();
- var ns = new Namespace (sym.name, get_src_com (begin));
+ var ns = new Namespace (sym.name, get_src (begin));
+ if (comment != null) {
+ ns.add_comment (comment);
+ comment = null;
+ }
set_attributes (ns, attrs);
expect (TokenType.EOL);
parse_declarations (ns);
accept (TokenType.EOL);
- var cl = new Class (sym.name, get_src_com (begin));
+ var cl = new Class (sym.name, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
cl.access = SymbolAccessibility.PRIVATE;
array_type.element_type.value_owned = false;
}
- var c = new Constant (id, type, initializer, get_src_com (begin));
+ var c = new Constant (id, type, initializer, get_src (begin), comment);
c.access = get_access (id);
if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
var type = parse_type ();
- var f = new Field (id, type, null, get_src_com (begin));
+ var f = new Field (id, type, null, get_src (begin), comment);
if (ModifierFlags.ABSTRACT in flags || ModifierFlags.VIRTUAL in flags || ModifierFlags.OVERRIDE in flags) {
Report.error (f.source_reference, "abstract, virtual, and override modifiers are not applicable to fields");
var begin = get_location ();
DataType type = new VoidType ();
expect (TokenType.INIT);
-
- var method = new Method (id, type, get_src_com (begin));
+
+ var method = new Method (id, type, get_src (begin), comment);
method.access = SymbolAccessibility.PUBLIC;
set_attributes (method, attrs);
expect (TokenType.CLOSE_PARENS);
-
/* deal with return value */
if (accept (TokenType.COLON)) {
type = parse_type ();
parse_type_parameter_list ();
}
-
- var method = new Method (id, type, get_src_com (begin));
+ var method = new Method (id, type, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
method.access = SymbolAccessibility.PRIVATE;
} else {
var type = parse_type (false);
- var prop = new Property (id, type, null, null, get_src_com (begin));
+ var prop = new Property (id, type, null, null, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
prop.access = SymbolAccessibility.PRIVATE;
} else {
type = new VoidType ();
}
- var sig = new Vala.Signal (id, type, get_src_com (begin));
+ var sig = new Vala.Signal (id, type, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
sig.access = SymbolAccessibility.PRIVATE;
} else {
expect (TokenType.INIT);
var flags = parse_member_declaration_modifiers ();
- var c = new Constructor (get_src_com (begin));
+ var c = new Constructor (get_src (begin));
if (ModifierFlags.STATIC in flags) {
c.binding = MemberBinding.STATIC;
} else if (ModifierFlags.CLASS in flags) {
Destructor parse_destructor_declaration (Gee.List<Attribute>? attrs) throws ParseError {
var begin = get_location ();
expect (TokenType.FINAL);
- var d = new Destructor (get_src_com (begin));
+ var d = new Destructor (get_src (begin));
accept_block ();
d.body = parse_block ();
return d;
if (accept (TokenType.COLON)) {
base_type = parse_type ();
}
- var st = new Struct (sym.name, get_src_com (begin));
+
+ var st = new Struct (sym.name, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
st.access = SymbolAccessibility.PRIVATE;
} else {
base_types.add (type);
} while (accept (TokenType.COMMA));
}
- var iface = new Interface (sym.name, get_src_com (begin));
+
+ var iface = new Interface (sym.name, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
iface.access = SymbolAccessibility.PRIVATE;
} else {
expect (TokenType.ENUM);
var flags = parse_type_declaration_modifiers ();
- var sym = parse_symbol_name ();
- var en = new Enum (sym.name, get_src_com (begin));
+ var sym = parse_symbol_name ();
+ var en = new Enum (sym.name, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
en.access = SymbolAccessibility.PRIVATE;
} else {
var value_attrs = parse_attributes ();
var value_begin = get_location ();
string id = parse_identifier ();
-
- var ev = new EnumValue (id, get_src (value_begin));
+ comment = scanner.pop_comment ();
+ var ev = new EnumValue (id, get_src (value_begin), comment);
set_attributes (ev, value_attrs);
if (accept (TokenType.ASSIGN)) {
var flags = parse_type_declaration_modifiers ();
var sym = parse_symbol_name ();
- var ed = new ErrorDomain (sym.name, get_src_com (begin));
+ var ed = new ErrorDomain (sym.name, get_src (begin), comment);
if (ModifierFlags.PRIVATE in flags) {
ed.access = SymbolAccessibility.PRIVATE;
} else {
var code_attrs = parse_attributes ();
var code_begin = get_location ();
string id = parse_identifier ();
-
- var ec = new ErrorCode (id, get_src (code_begin));
+ comment = scanner.pop_comment ();
+ var ec = new ErrorCode (id, get_src (code_begin), comment);
set_attributes (ec, code_attrs);
if (accept (TokenType.ASSIGN)) {
ec.value = parse_expression ();
while (sym.inner != null) {
sym = sym.inner;
var ns = new Namespace (sym.name, ed.source_reference);
-
if (result is Namespace) {
ns.add_namespace ((Namespace) result);
} else {
expect (TokenType.CONSTRUCT);
parse_member_declaration_modifiers ();
-
if (accept (TokenType.OPEN_PARENS)) {
/* create default name using class name */
- method = new CreationMethod (class_name, null, get_src_com (begin));
+ method = new CreationMethod (class_name, null, get_src (begin), comment);
} else {
var sym = parse_symbol_name ();
if (sym.inner == null) {
if (sym.name != class_name) {
- method = new CreationMethod (class_name, sym.name, get_src_com (begin));
+ method = new CreationMethod (class_name, sym.name, get_src (begin), comment);
} else {
- method = new CreationMethod (sym.name, null, get_src_com (begin));
+ method = new CreationMethod (sym.name, null, get_src (begin), comment);
}
} else {
- method = new CreationMethod (sym.inner.name, sym.name, get_src_com (begin));
+ method = new CreationMethod (sym.inner.name, sym.name, get_src (begin), comment);
}
expect (TokenType.OPEN_PARENS);
}
-
if (current () != TokenType.CLOSE_PARENS) {
do {
var param = parse_parameter ();
type = new VoidType ();
}
- var d = new Delegate (sym.name, type, get_src_com (begin));
+ var d = new Delegate (sym.name, type, get_src (begin), comment);
if (accept (TokenType.RAISES)) {
do {
while (sym.inner != null) {
sym = sym.inner;
var ns = new Namespace (sym.name, d.source_reference);
-
if (result is Namespace) {
ns.add_namespace ((Namespace) result);
} else {
TokenType last_token;
bool parse_started;
- string _comment;
+ Comment _comment;
Conditional[] conditional_stack;
if (current[1] == '/') {
// single-line comment
current += 2;
- char* begin = current;
-
+
// skip until end of line or end of file
while (current < end && current[0] != '\n') {
current++;
}
-
- push_comment (((string) begin).ndup ((long) (current - begin)), line == 1);
/* do not ignore EOL if comment does not exclusively occupy the line */
if (current[0] == '\n' && last_token == TokenType.EOL) {
}
} else {
// delimited comment
+ SourceReference source_reference = null;
+
+ if (current[2] == '*') {
+ source_reference = new SourceReference (source_file, line, column, line, column);
+ }
+
current += 2;
char* begin = current;
int begin_line = line;
Report.error (new SourceReference (source_file, line, column, line, column), "syntax error, expected */");
return true;
}
- push_comment (((string) begin).ndup ((long) (current - begin)), begin_line == 1);
+
+ if (source_reference != null) {
+ string comment = ((string) begin).ndup ((long) (current - begin));
+ push_comment (comment, source_reference, begin_line == 1 && comment[0] != '*');
+ }
+
current += 2;
column += 2;
}
}
}
-
-
-
- void push_comment (string comment_item, bool file_comment) {
- if (_comment == null) {
- _comment = comment_item;
- } else {
- _comment = "%s\n%s".printf (_comment, comment_item);
+ void push_comment (string comment_item, SourceReference source_reference, bool file_comment) {
+ if (comment_item[0] == '*') {
+ _comment = new Comment (comment_item, source_reference);
}
+
if (file_comment) {
- source_file.comment = _comment;
+ source_file.add_comment (new Comment (comment_item, source_reference));
_comment = null;
}
}
*
* @return saved comment
*/
- public string? pop_comment () {
+ public Comment? pop_comment () {
if (_comment == null) {
return null;
}
- var result_builder = new StringBuilder (_comment);
+ var comment = _comment;
_comment = null;
-
- weak string index;
- while ((index = result_builder.str.chr (-1, '\t')) != null) {
- result_builder.erase (result_builder.str.pointer_to_offset (index), 1);
- }
-
- return result_builder.str;
+ return comment;
}
-
- bool pp_whitespace () {
+
+ bool pp_whitespace () {
bool found = false;
while (current < end && current[0].isspace () && current[0] != '\n') {
found = true;
* @param source reference to source code
* @return newly created interface
*/
- public Interface (string name, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public Interface (string name, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
}
/**
* Represents a general class member.
*/
public abstract class Vala.Member : Symbol {
+ public Comment comment { get; set; }
+
private Gee.List<string> cheader_filenames = new ArrayList<string> ();
/**
*/
public bool hides { get; set; }
- public Member (string? name, SourceReference? source_reference) {
+ public Member (string? name, SourceReference? source_reference, Comment? comment = null) {
base (name, source_reference);
+ this.comment = comment;
}
public override void accept (CodeVisitor visitor) {
* @param source reference to source code
* @return newly created method
*/
- public Method (string? name, DataType return_type, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public Method (string? name, DataType return_type, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
this.return_type = return_type;
carray_length_parameter_position = -3;
private Gee.List<Field> fields = new ArrayList<Field> ();
private Gee.List<Method> methods = new ArrayList<Method> ();
+ private Gee.List<Comment> comments = new ArrayList<Comment> ();
+
private Gee.List<string> cprefixes = new ArrayList<string> ();
private string lower_case_cprefix;
access = SymbolAccessibility.PUBLIC;
}
+ public void add_comment (Comment comment) {
+ comments.add (comment);
+ }
+
+ /**
+ * Returns a copy of the list of namespaces.
+ *
+ * @return comment list
+ */
+ public Gee.List<Comment> get_comments () {
+ return new ReadOnlyList<Comment> (comments);
+ }
+
/**
* Adds the specified namespace to this source file.
*
if (old_ns.external_package && !ns.external_package) {
old_ns.source_reference = ns.source_reference;
}
+
foreach (Namespace sub_ns in ns.get_namespaces ()) {
old_ns.add_namespace (sub_ns);
}
foreach (Method m in ns.get_methods ()) {
old_ns.add_method (m);
}
+ foreach (Comment c in ns.get_comments ()) {
+ old_ns.add_comment (c);
+ }
} else {
namespaces.add (ns);
scope.add (ns.name, ns);
public abstract class Vala.ObjectTypeSymbol : TypeSymbol {
private Gee.List<TypeParameter> type_parameters = new ArrayList<TypeParameter> ();
- public ObjectTypeSymbol (string name, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public ObjectTypeSymbol (string name, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
}
public abstract Gee.List<Method> get_methods ();
// number of tokens in buffer
int size;
- string comment;
+ Comment comment;
const int BUFFER_SIZE = 32;
return new SourceReference (scanner.source_file, begin.line, begin.column, tokens[last_index].end.line, tokens[last_index].end.column);
}
- SourceReference get_src_com (SourceLocation begin) {
- int last_index = (index + BUFFER_SIZE - 1) % BUFFER_SIZE;
-
- var src = new SourceReference.with_comment (scanner.source_file, begin.line, begin.column, tokens[last_index].end.line, tokens[last_index].end.column, comment);
- comment = null;
- return src;
- }
-
SourceReference get_current_src () {
return new SourceReference (scanner.source_file, tokens[index].begin.line, tokens[index].begin.column, tokens[index].end.line, tokens[index].end.column);
}
public void parse_file (SourceFile source_file) {
scanner = new Scanner (source_file);
+ parse_file_comments ();
index = -1;
size = 0;
next ();
+
try {
parse_using_directives ();
parse_declarations (context.root, true);
scanner = null;
}
+ void parse_file_comments () {
+ scanner.parse_file_comments ();
+ }
+
void skip_symbol_name () throws ParseError {
do {
skip_identifier ();
try {
Statement stmt = null;
bool is_decl = false;
+
comment = scanner.pop_comment ();
switch (current ()) {
case TokenType.OPEN_BRACE:
comment = scanner.pop_comment ();
- var block = new Block (get_src_com (get_location ()));
+ var block = new Block (get_src (get_location ()));
block.add_statement (parse_embedded_statement_without_block ());
return block;
Block parse_block () throws ParseError {
var begin = get_location ();
expect (TokenType.OPEN_BRACE);
- var block = new Block (get_src_com (begin));
+ var block = new Block (get_src (begin));
parse_statements (block);
if (!accept (TokenType.CLOSE_BRACE)) {
// only report error if it's not a secondary error
Statement parse_empty_statement () throws ParseError {
var begin = get_location ();
expect (TokenType.SEMICOLON);
- return new EmptyStatement (get_src_com (begin));
+ return new EmptyStatement (get_src (begin));
}
void parse_local_variable_declarations (Block block) throws ParseError {
if (accept (TokenType.ASSIGN)) {
initializer = parse_expression ();
}
- return new LocalVariable (type, id, initializer, get_src_com (begin));
+ return new LocalVariable (type, id, initializer, get_src (begin));
}
Statement parse_expression_statement () throws ParseError {
var begin = get_location ();
var expr = parse_statement_expression ();
expect (TokenType.SEMICOLON);
- return new ExpressionStatement (expr, get_src_com (begin));
+ return new ExpressionStatement (expr, get_src (begin));
}
Expression parse_statement_expression () throws ParseError {
expect (TokenType.OPEN_PARENS);
var condition = parse_expression ();
expect (TokenType.CLOSE_PARENS);
- var src = get_src_com (begin);
+ var src = get_src (begin);
var true_stmt = parse_embedded_statement ();
Block false_stmt = null;
if (accept (TokenType.ELSE)) {
expect (TokenType.OPEN_PARENS);
var condition = parse_expression ();
expect (TokenType.CLOSE_PARENS);
- var stmt = new SwitchStatement (condition, get_src_com (begin));
+ var stmt = new SwitchStatement (condition, get_src (begin));
expect (TokenType.OPEN_BRACE);
while (current () != TokenType.CLOSE_BRACE) {
- var section = new SwitchSection (get_src_com (begin));
+ var section = new SwitchSection (get_src (begin));
do {
if (accept (TokenType.CASE)) {
- section.add_label (new SwitchLabel (parse_expression (), get_src_com (begin)));
+ section.add_label (new SwitchLabel (parse_expression (), get_src (begin)));
} else {
expect (TokenType.DEFAULT);
- section.add_label (new SwitchLabel.with_default (get_src_com (begin)));
+ section.add_label (new SwitchLabel.with_default (get_src (begin)));
}
expect (TokenType.COLON);
} while (current () == TokenType.CASE || current () == TokenType.DEFAULT);
var condition = parse_expression ();
expect (TokenType.CLOSE_PARENS);
var body = parse_embedded_statement ();
- return new WhileStatement (condition, body, get_src_com (begin));
+ return new WhileStatement (condition, body, get_src (begin));
}
Statement parse_do_statement () throws ParseError {
var condition = parse_expression ();
expect (TokenType.CLOSE_PARENS);
expect (TokenType.SEMICOLON);
- return new DoStatement (body, condition, get_src_com (begin));
+ return new DoStatement (body, condition, get_src (begin));
}
Statement parse_for_statement () throws ParseError {
} while (accept (TokenType.COMMA));
}
expect (TokenType.CLOSE_PARENS);
- var src = get_src_com (begin);
+ var src = get_src (begin);
var body = parse_embedded_statement ();
var stmt = new ForStatement (condition, body, src);
foreach (Expression init in initializer_list) {
expect (TokenType.IN);
var collection = parse_expression ();
expect (TokenType.CLOSE_PARENS);
- var src = get_src_com (begin);
+ var src = get_src (begin);
var body = parse_embedded_statement ();
return new ForeachStatement (type, id, collection, body, src);
}
var begin = get_location ();
expect (TokenType.BREAK);
expect (TokenType.SEMICOLON);
- return new BreakStatement (get_src_com (begin));
+ return new BreakStatement (get_src (begin));
}
Statement parse_continue_statement () throws ParseError {
var begin = get_location ();
expect (TokenType.CONTINUE);
expect (TokenType.SEMICOLON);
- return new ContinueStatement (get_src_com (begin));
+ return new ContinueStatement (get_src (begin));
}
Statement parse_return_statement () throws ParseError {
expr = parse_expression ();
}
expect (TokenType.SEMICOLON);
- return new ReturnStatement (expr, get_src_com (begin));
+ return new ReturnStatement (expr, get_src (begin));
}
Statement parse_yield_statement () throws ParseError {
expect (TokenType.THROW);
var expr = parse_expression ();
expect (TokenType.SEMICOLON);
- return new ThrowStatement (expr, get_src_com (begin));
+ return new ThrowStatement (expr, get_src (begin));
}
Statement parse_try_statement () throws ParseError {
} else {
finally_clause = parse_finally_clause ();
}
- var stmt = new TryStatement (try_block, finally_clause, get_src_com (begin));
+ var stmt = new TryStatement (try_block, finally_clause, get_src (begin));
foreach (CatchClause clause in catch_clauses) {
stmt.add_catch_clause (clause);
}
var expr = parse_expression ();
expect (TokenType.CLOSE_PARENS);
var stmt = parse_embedded_statement ();
- return new LockStatement (expr, stmt, get_src_com (begin));
+ return new LockStatement (expr, stmt, get_src (begin));
}
Statement parse_delete_statement () throws ParseError {
expect (TokenType.DELETE);
var expr = parse_expression ();
expect (TokenType.SEMICOLON);
- return new DeleteStatement (expr, get_src_com (begin));
+ return new DeleteStatement (expr, get_src (begin));
}
Gee.List<Attribute>? parse_attributes () throws ParseError {
var begin = get_location ();
expect (TokenType.NAMESPACE);
var sym = parse_symbol_name ();
- var ns = new Namespace (sym.name, get_src_com (begin));
+ var ns = new Namespace (sym.name, get_src (begin));
+ if (comment != null) {
+ ns.add_comment (comment);
+ comment = null;
+ }
+
set_attributes (ns, attrs);
parse_declarations (ns);
} while (accept (TokenType.COMMA));
}
- var cl = new Class (sym.name, get_src_com (begin));
+ var cl = new Class (sym.name, get_src (begin), comment);
cl.access = access;
if (ModifierFlags.ABSTRACT in flags) {
cl.is_abstract = true;
array_type.element_type.value_owned = false;
}
- var c = new Constant (id, type, initializer, get_src_com (begin));
+ var c = new Constant (id, type, initializer, get_src (begin), comment);
c.access = access;
if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
c.external = true;
type = parse_inline_array_type (type);
- var f = new Field (id, type, null, get_src_com (begin));
+ var f = new Field (id, type, null, get_src (begin), comment);
f.access = access;
set_attributes (f, attrs);
if (ModifierFlags.STATIC in flags) {
var type = parse_type ();
string id = parse_identifier ();
var type_param_list = parse_type_parameter_list ();
- var method = new Method (id, type, get_src_com (begin));
+ var method = new Method (id, type, get_src (begin), comment);
method.access = access;
set_attributes (method, attrs);
foreach (TypeParameter type_param in type_param_list) {
}
string id = parse_identifier ();
- var prop = new Property (id, type, null, null, get_src_com (begin));
+ var prop = new Property (id, type, null, null, get_src (begin), comment);
prop.access = access;
set_attributes (prop, attrs);
if (ModifierFlags.STATIC in flags) {
expect (TokenType.SIGNAL);
var type = parse_type ();
string id = parse_identifier ();
- var sig = new Signal (id, type, get_src_com (begin));
+ var sig = new Signal (id, type, get_src (begin), comment);
sig.access = access;
set_attributes (sig, attrs);
if (ModifierFlags.VIRTUAL in flags) {
if (ModifierFlags.NEW in flags) {
throw new ParseError.SYNTAX (get_error ("`new' modifier not allowed on constructor"));
}
- var c = new Constructor (get_src_com (begin));
+ var c = new Constructor (get_src (begin));
if (ModifierFlags.STATIC in flags) {
c.binding = MemberBinding.STATIC;
} else if (ModifierFlags.CLASS in flags) {
if (ModifierFlags.NEW in flags) {
throw new ParseError.SYNTAX (get_error ("`new' modifier not allowed on destructor"));
}
- var d = new Destructor (get_src_com (begin));
+ var d = new Destructor (get_src (begin));
if (ModifierFlags.STATIC in flags) {
d.binding = MemberBinding.STATIC;
} else if (ModifierFlags.CLASS in flags) {
if (accept (TokenType.COLON)) {
base_type = parse_type ();
}
- var st = new Struct (sym.name, get_src_com (begin));
+ var st = new Struct (sym.name, get_src (begin), comment);
st.access = access;
if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
st.external = true;
Symbol result = st;
while (sym.inner != null) {
sym = sym.inner;
+
var ns = new Namespace (sym.name, st.source_reference);
if (result is Namespace) {
ns.add_namespace ((Namespace) result);
base_types.add (type);
} while (accept (TokenType.COMMA));
}
- var iface = new Interface (sym.name, get_src_com (begin));
+ var iface = new Interface (sym.name, get_src (begin), comment);
iface.access = access;
if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
iface.external = true;
var flags = parse_type_declaration_modifiers ();
expect (TokenType.ENUM);
var sym = parse_symbol_name ();
- var en = new Enum (sym.name, get_src_com (begin));
+ var en = new Enum (sym.name, get_src (begin), comment);
en.access = access;
if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
en.external = true;
var value_attrs = parse_attributes ();
var value_begin = get_location ();
string id = parse_identifier ();
- var ev = new EnumValue (id, get_src (value_begin));
+ comment = scanner.pop_comment ();
+ var ev = new EnumValue (id, get_src (value_begin), comment);
set_attributes (ev, value_attrs);
if (accept (TokenType.ASSIGN)) {
ev.value = parse_expression ();
var flags = parse_type_declaration_modifiers ();
expect (TokenType.ERRORDOMAIN);
var sym = parse_symbol_name ();
- var ed = new ErrorDomain (sym.name, get_src_com (begin));
+ var ed = new ErrorDomain (sym.name, get_src (begin), comment);
ed.access = access;
if (ModifierFlags.EXTERN in flags || scanner.source_file.external_package) {
ed.external = true;
var code_attrs = parse_attributes ();
var code_begin = get_location ();
string id = parse_identifier ();
- var ec = new ErrorCode (id, get_src (code_begin));
+ comment = scanner.pop_comment ();
+ var ec = new ErrorCode (id, get_src (code_begin), comment);
set_attributes (ec, code_attrs);
if (accept (TokenType.ASSIGN)) {
ec.value = parse_expression ();
}
CreationMethod method;
if (sym.inner == null) {
- method = new CreationMethod (sym.name, null, get_src_com (begin));
+ method = new CreationMethod (sym.name, null, get_src (begin), comment);
} else {
- method = new CreationMethod (sym.inner.name, sym.name, get_src_com (begin));
+ method = new CreationMethod (sym.inner.name, sym.name, get_src (begin), comment);
}
if (ModifierFlags.EXTERN in flags) {
method.external = true;
var type = parse_type ();
var sym = parse_symbol_name ();
var type_param_list = parse_type_parameter_list ();
- var d = new Delegate (sym.name, type, get_src_com (begin));
+ var d = new Delegate (sym.name, type, get_src (begin), comment);
d.access = access;
set_attributes (d, attrs);
if (ModifierFlags.STATIC in flags) {
* @param source reference to source code
* @return newly created property
*/
- public Property (string name, DataType? property_type, PropertyAccessor? get_accessor, PropertyAccessor? set_accessor, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public Property (string name, DataType? property_type, PropertyAccessor? get_accessor, PropertyAccessor? set_accessor, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
this.property_type = property_type;
this.get_accessor = get_accessor;
this.set_accessor = set_accessor;
int line;
int column;
- string _comment;
+ Comment _comment;
Conditional[] conditional_stack;
return found;
}
- bool comment () {
+ bool comment (bool file_comment = false) {
if (current > end - 2
|| current[0] != '/'
|| (current[1] != '/' && current[1] != '*')) {
}
if (current[1] == '/') {
+ SourceReference source_reference = null;
+ if (file_comment) {
+ source_reference = new SourceReference (source_file, line, column, line, column);
+ }
+
// single-line comment
current += 2;
char* begin = current;
+
// skip until end of line or end of file
while (current < end && current[0] != '\n') {
current++;
}
- push_comment (((string) begin).ndup ((long) (current - begin)), line == 1);
+
+ if (source_reference != null) {
+ push_comment (((string) begin).ndup ((long) (current - begin)), source_reference, file_comment);
+ }
} else {
- // delimited comment
+ SourceReference source_reference = null;
+
+ if (file_comment && current[2] == '*') {
+ return false;
+ }
+
+ if (current[2] == '*' || file_comment) {
+ source_reference = new SourceReference (source_file, line, column, line, column);
+ }
+
current += 2;
+
char* begin = current;
- int begin_line = line;
while (current < end - 1
&& (current[0] != '*' || current[1] != '/')) {
if (current[0] == '\n') {
current++;
column++;
}
+
if (current == end - 1) {
Report.error (new SourceReference (source_file, line, column, line, column), "syntax error, expected */");
return true;
}
- push_comment (((string) begin).ndup ((long) (current - begin)), begin_line == 1);
+
+ if (source_reference != null) {
+ push_comment (((string) begin).ndup ((long) (current - begin)), source_reference, file_comment);
+ }
+
current += 2;
column += 2;
}
}
}
- void push_comment (string comment_item, bool file_comment) {
- if (_comment == null) {
- _comment = comment_item;
- } else {
- _comment = "%s\n%s".printf (_comment, comment_item);
+ public void parse_file_comments () {
+ while (whitespace () || comment (true)) {
+ }
+ }
+
+ void push_comment (string comment_item, SourceReference source_reference, bool file_comment) {
+ if (comment_item[0] == '*') {
+ _comment = new Comment (comment_item, source_reference);
}
+
if (file_comment) {
- source_file.comment = _comment;
+ source_file.add_comment (new Comment (comment_item, source_reference));
_comment = null;
}
}
-
+
/**
* Clears and returns the content of the comment stack.
*
* @return saved comment
*/
- public string? pop_comment () {
+ public Comment? pop_comment () {
if (_comment == null) {
return null;
}
-
- var result_builder = new StringBuilder (_comment);
+
+ var comment = _comment;
_comment = null;
-
- string* index;
- while ((index = result_builder.str.chr (-1, '\t')) != null) {
- result_builder.erase ((long) (index - (string*) result_builder.str), 1);
- }
-
- return result_builder.str;
+ return comment;
}
}
* @param source reference to source code
* @return newly created signal
*/
- public Signal (string name, DataType return_type, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public Signal (string name, DataType return_type, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
this.return_type = return_type;
}
*/
public string filename { get; set; }
- /**
- * The header comment of this source file.
- */
- public string comment { get; set; }
/**
* Specifies whether this file is a VAPI package file.
}
}
+ private ArrayList<Comment> comments = new ArrayList<Comment> ();
+
private Gee.List<UsingDirective> using_directives = new ArrayList<UsingDirective> ();
private Gee.List<CodeNode> nodes = new ArrayList<CodeNode> ();
this.context = context;
this.content = content;
}
-
+
+ /**
+ * Adds a header comment to this source file.
+ */
+ public void add_comment (Comment comment) {
+ comments.add (comment);
+ }
+
+ /**
+ * Returns a copy of the list of header comments.
+ *
+ * @return list of comments
+ */
+ public Gee.List<Comment> get_comments () {
+ return new ReadOnlyList<Comment> (comments);
+ }
+
/**
* Adds a new using directive with the specified namespace.
*
* The last column number of the referenced source code.
*/
public int last_column { get; set; }
-
- /**
- * The text describing the referenced source code.
- */
- public string comment { get; set; }
/**
* Creates a new source reference.
last_column = _last_column;
}
- /**
- * Creates a new commented source reference.
- *
- * @param file a source file
- * @param first_line first line number
- * @param first_column first column number
- * @param last_line last line number
- * @param last_column last column number
- * @param comment code comment
- * @return newly created source reference
- */
- public SourceReference.with_comment (SourceFile _file, int _first_line, int _first_column, int _last_line, int _last_column, string? _comment) {
- file = _file;
- first_line = _first_line;
- first_column = _first_column;
- last_line = _last_line;
- last_column = _last_column;
- comment = _comment;
- }
-
/**
* Returns a string representation of this source reference.
*
* @param source_reference reference to source code
* @return newly created struct
*/
- public Struct (string name, SourceReference? source_reference = null) {
- base (name, source_reference);
+ public Struct (string name, SourceReference? source_reference = null, Comment? comment = null) {
+ base (name, source_reference, comment);
}
/**
* code or imported from an external library with a Vala API file.
*/
public abstract class Vala.TypeSymbol : Symbol {
+ public Comment? comment { get; set; }
+
private Gee.List<string> cheader_filenames = new ArrayList<string> ();
- public TypeSymbol (string? name, SourceReference? source_reference = null) {
+ public TypeSymbol (string? name, SourceReference? source_reference = null, Comment? comment = null) {
base (name, source_reference);
+ this.comment = comment;
}
/**