[vala/wip/bug769229: 1/6] Support [FormatArg] attribute for parameters
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/bug769229: 1/6] Support [FormatArg] attribute for parameters
- Date: Wed, 2 Nov 2016 19:56:40 +0000 (UTC)
commit 45040eb2f5603ffb55202aa0c1edae8a750a607a
Author: Jürg Billeter <j bitron ch>
Date: Tue Nov 1 17:48:15 2016 +0100
Support [FormatArg] attribute for parameters
This attribute specifies that the method takes and returns a printf
or scanf format string without modifying the order or types of expected
arguments, e.g., to translate the format string. This allows the
compiler to check the printf/scanf arguments.
vala/valamethod.vala | 9 +++++++++
vala/valamethodcall.vala | 16 ++++++++++++++--
vala/valaobjectcreationexpression.vala | 4 ++--
vala/valaparameter.vala | 6 ++++++
vala/valastringliteral.vala | 14 ++++++++++++++
vala/valausedattr.vala | 1 +
6 files changed, 46 insertions(+), 4 deletions(-)
---
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index f0f1980..f073c6e 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -1047,6 +1047,15 @@ public class Vala.Method : Subroutine, Callable {
get_captured_variables ((Collection<LocalVariable>) collection);
}
}
+
+ public int get_format_arg () {
+ for (int i = 0; i < parameters.size; i++) {
+ if (parameters[i].format_arg) {
+ return i;
+ }
+ }
+ return -1;
+ }
}
// vim:sw=8 noet
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index d3889eb..9d3b141 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -434,7 +434,7 @@ public class Vala.MethodCall : Expression {
StringLiteral format_literal = null;
if (last_arg != null) {
// use last argument as format string
- format_literal = last_arg as StringLiteral;
+ format_literal = StringLiteral.get_format_literal (last_arg);
if (format_literal == null && args.size == params.size - 1) {
// insert "%s" to avoid issues with embedded %
format_literal = new StringLiteral ("\"%s\"");
@@ -454,7 +454,7 @@ public class Vala.MethodCall : Expression {
// use instance as format string for string.printf (...)
var ma = call as MemberAccess;
if (ma != null) {
- format_literal = ma.inner as StringLiteral;
+ format_literal = StringLiteral.get_format_literal (ma.inner);
}
}
if (format_literal != null) {
@@ -722,4 +722,16 @@ public class Vala.MethodCall : Expression {
arg.get_used_variables (collection);
}
}
+
+ public StringLiteral? get_format_literal () {
+ var mtype = this.call.value_type as MethodType;
+ if (mtype != null) {
+ int format_arg = mtype.method_symbol.get_format_arg ();
+ if (format_arg >= 0 && format_arg < argument_list.size) {
+ return StringLiteral.get_format_literal (argument_list[format_arg]);
+ }
+ }
+
+ return null;
+ }
}
diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala
index 5a271b7..c4b119a 100644
--- a/vala/valaobjectcreationexpression.vala
+++ b/vala/valaobjectcreationexpression.vala
@@ -388,7 +388,7 @@ public class Vala.ObjectCreationExpression : Expression {
StringLiteral format_literal = null;
if (last_arg != null) {
// use last argument as format string
- format_literal = last_arg as StringLiteral;
+ format_literal = StringLiteral.get_format_literal (last_arg);
if (format_literal == null && args.size == m.get_parameters ().size -
1) {
// insert "%s" to avoid issues with embedded %
format_literal = new StringLiteral ("\"%s\"");
@@ -457,7 +457,7 @@ public class Vala.ObjectCreationExpression : Expression {
Report.error (source_reference, "Invalid type for argument 1");
}
- var format_literal = ex as StringLiteral;
+ var format_literal = StringLiteral.get_format_literal (ex);
if (format_literal != null) {
var format = format_literal.eval ();
if (!context.analyzer.check_print_format (format, arg_it,
source_reference)) {
diff --git a/vala/valaparameter.vala b/vala/valaparameter.vala
index 67d172e..3982071 100644
--- a/vala/valaparameter.vala
+++ b/vala/valaparameter.vala
@@ -44,6 +44,12 @@ public class Vala.Parameter : Variable {
public bool captured { get; set; }
+ public bool format_arg {
+ get {
+ return get_attribute ("FormatArg") != null;
+ }
+ }
+
/**
* The base parameter of this parameter relative to the base method.
*/
diff --git a/vala/valastringliteral.vala b/vala/valastringliteral.vala
index e54a9c4..72970c6 100644
--- a/vala/valastringliteral.vala
+++ b/vala/valastringliteral.vala
@@ -96,4 +96,18 @@ public class Vala.StringLiteral : Literal {
codegen.visit_expression (this);
}
+
+ public static StringLiteral? get_format_literal (Expression expr) {
+ var format_literal = expr as StringLiteral;
+ if (format_literal != null) {
+ return format_literal;
+ }
+
+ var call = expr as MethodCall;
+ if (call != null) {
+ return call.get_format_literal ();
+ }
+
+ return null;
+ }
}
diff --git a/vala/valausedattr.vala b/vala/valausedattr.vala
index 14fe1d2..2e5840d 100644
--- a/vala/valausedattr.vala
+++ b/vala/valausedattr.vala
@@ -68,6 +68,7 @@ public class Vala.UsedAttr : CodeVisitor {
"SimpleType", "",
"PrintfFormat", "",
"ScanfFormat", "",
+ "FormatArg", "",
"GtkChild", "name", "internal", "",
"GtkTemplate", "ui", "",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]