vala r1987 - in trunk: . vala
- From: juergbi svn gnome org
- To: svn-commits-list gnome org
- Subject: vala r1987 - in trunk: . vala
- Date: Wed, 5 Nov 2008 22:03:37 +0000 (UTC)
Author: juergbi
Date: Wed Nov 5 22:03:37 2008
New Revision: 1987
URL: http://svn.gnome.org/viewvc/vala?rev=1987&view=rev
Log:
2008-11-05 JÃrg Billeter <j bitron ch>
* vala/valainvocationexpression.vala:
* vala/valasemanticanalyzer.vala:
Move invocation expression checking to InvocationExpression.check
Modified:
trunk/ChangeLog
trunk/vala/valainvocationexpression.vala
trunk/vala/valasemanticanalyzer.vala
Modified: trunk/vala/valainvocationexpression.vala
==============================================================================
--- trunk/vala/valainvocationexpression.vala (original)
+++ trunk/vala/valainvocationexpression.vala Wed Nov 5 22:03:37 2008
@@ -120,4 +120,306 @@
public override bool is_pure () {
return false;
}
+
+ public override bool check (SemanticAnalyzer analyzer) {
+ if (checked) {
+ return !error;
+ }
+
+ checked = true;
+
+ call.accept (analyzer);
+
+ if (call.error) {
+ /* if method resolving didn't succeed, skip this check */
+ error = true;
+ return false;
+ }
+
+ if (call is MemberAccess) {
+ var ma = (MemberAccess) call;
+ if (ma.prototype_access) {
+ error = true;
+ Report.error (source_reference, "Access to instance member `%s' denied".printf (call.symbol_reference.get_full_name ()));
+ return false;
+ }
+ }
+
+ var mtype = call.value_type;
+
+ if (mtype is ObjectType) {
+ // constructor chain-up
+ var cm = analyzer.find_current_method () as CreationMethod;
+ assert (cm != null);
+ if (cm.chain_up) {
+ error = true;
+ Report.error (source_reference, "Multiple constructor calls in the same constructor are not permitted");
+ return false;
+ }
+ cm.chain_up = true;
+ }
+
+ // check for struct construction
+ if (call is MemberAccess &&
+ ((call.symbol_reference is CreationMethod
+ && call.symbol_reference.parent_symbol is Struct)
+ || call.symbol_reference is Struct)) {
+ var struct_creation_expression = new ObjectCreationExpression ((MemberAccess) call, source_reference);
+ struct_creation_expression.struct_creation = true;
+ foreach (Expression arg in get_argument_list ()) {
+ struct_creation_expression.add_argument (arg);
+ }
+ struct_creation_expression.target_type = target_type;
+ analyzer.replaced_nodes.add (this);
+ parent_node.replace_expression (this, struct_creation_expression);
+ struct_creation_expression.accept (analyzer);
+ return false;
+ } else if (call is MemberAccess
+ && call.symbol_reference is CreationMethod) {
+ // constructor chain-up
+ var cm = analyzer.find_current_method () as CreationMethod;
+ assert (cm != null);
+ if (cm.chain_up) {
+ error = true;
+ Report.error (source_reference, "Multiple constructor calls in the same constructor are not permitted");
+ return false;
+ }
+ cm.chain_up = true;
+ }
+
+ Gee.List<FormalParameter> params;
+
+ if (mtype != null && mtype.is_invokable ()) {
+ params = mtype.get_parameters ();
+ } else {
+ error = true;
+ Report.error (source_reference, "invocation not supported in this context");
+ return false;
+ }
+
+ Expression last_arg = null;
+
+ var args = get_argument_list ();
+ Iterator<Expression> arg_it = args.iterator ();
+ foreach (FormalParameter param in params) {
+ if (param.ellipsis) {
+ break;
+ }
+
+ if (arg_it.next ()) {
+ Expression arg = arg_it.get ();
+
+ /* store expected type for callback parameters */
+ arg.target_type = param.parameter_type;
+
+ // resolve generic type parameters
+ var ma = call as MemberAccess;
+ if (arg.target_type.type_parameter != null) {
+ if (ma != null && ma.inner != null) {
+ arg.target_type = analyzer.get_actual_type (ma.inner.value_type, ma.symbol_reference, arg.target_type, arg);
+ assert (arg.target_type != null);
+ }
+ }
+
+ last_arg = arg;
+ }
+ }
+
+ // printf arguments
+ if (mtype is MethodType && ((MethodType) mtype).method_symbol.printf_format) {
+ StringLiteral format_literal = null;
+ if (last_arg != null) {
+ // use last argument as format string
+ format_literal = last_arg as StringLiteral;
+ } else {
+ // use instance as format string for string.printf (...)
+ var ma = call as MemberAccess;
+ if (ma != null) {
+ format_literal = ma.inner as StringLiteral;
+ }
+ }
+ if (format_literal != null) {
+ string format = format_literal.eval ();
+
+ bool unsupported_format = false;
+
+ weak string format_it = format;
+ unichar c = format_it.get_char ();
+ while (c != '\0') {
+ if (c != '%') {
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ continue;
+ }
+
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ // flags
+ while (c == '#' || c == '0' || c == '-' || c == ' ' || c == '+') {
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ }
+ // field width
+ while (c >= '0' && c <= '9') {
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ }
+ // precision
+ if (c == '.') {
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ while (c >= '0' && c <= '9') {
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ }
+ }
+ // length modifier
+ int length = 0;
+ if (c == 'h') {
+ length = -1;
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ if (c == 'h') {
+ length = -2;
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ }
+ } else if (c == 'l') {
+ length = 1;
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ } else if (c == 'z') {
+ length = 2;
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ }
+ // conversion specifier
+ DataType param_type = null;
+ if (c == 'd' || c == 'i' || c == 'c') {
+ // integer
+ if (length == -2) {
+ param_type = analyzer.int8_type;
+ } else if (length == -1) {
+ param_type = analyzer.short_type;
+ } else if (length == 0) {
+ param_type = analyzer.int_type;
+ } else if (length == 1) {
+ param_type = analyzer.long_type;
+ } else if (length == 2) {
+ param_type = analyzer.ssize_t_type;
+ }
+ } else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') {
+ // unsigned integer
+ if (length == -2) {
+ param_type = analyzer.uchar_type;
+ } else if (length == -1) {
+ param_type = analyzer.ushort_type;
+ } else if (length == 0) {
+ param_type = analyzer.uint_type;
+ } else if (length == 1) {
+ param_type = analyzer.ulong_type;
+ } else if (length == 2) {
+ param_type = analyzer.size_t_type;
+ }
+ } else if (c == 'e' || c == 'E' || c == 'f' || c == 'F'
+ || c == 'g' || c == 'G' || c == 'a' || c == 'A') {
+ // double
+ param_type = analyzer.double_type;
+ } else if (c == 's') {
+ // string
+ param_type = analyzer.string_type;
+ } else if (c == 'p') {
+ // pointer
+ param_type = new PointerType (new VoidType ());
+ } else if (c == '%') {
+ // literal %
+ } else {
+ unsupported_format = true;
+ break;
+ }
+ if (c != '\0') {
+ format_it = format_it.next_char ();
+ c = format_it.get_char ();
+ }
+ if (param_type != null) {
+ if (arg_it.next ()) {
+ Expression arg = arg_it.get ();
+
+ arg.target_type = param_type;
+ } else {
+ Report.error (source_reference, "Too few arguments for specified format");
+ return false;
+ }
+ }
+ }
+ if (!unsupported_format && arg_it.next ()) {
+ Report.error (source_reference, "Too many arguments for specified format");
+ return false;
+ }
+ }
+ }
+
+ foreach (Expression arg in get_argument_list ()) {
+ arg.accept (analyzer);
+ }
+
+ DataType ret_type;
+
+ ret_type = mtype.get_return_type ();
+ params = mtype.get_parameters ();
+
+ if (ret_type is VoidType) {
+ // void return type
+ if (!(parent_node is ExpressionStatement)
+ && !(parent_node is ForStatement)
+ && !(parent_node is YieldStatement)) {
+ // A void method invocation can be in the initializer or
+ // iterator of a for statement
+ error = true;
+ Report.error (source_reference, "invocation of void method not allowed as expression");
+ return false;
+ }
+ }
+
+ // resolve generic return values
+ var ma = call as MemberAccess;
+ if (ret_type.type_parameter != null) {
+ if (ma != null && ma.inner != null) {
+ ret_type = analyzer.get_actual_type (ma.inner.value_type, ma.symbol_reference, ret_type, this);
+ if (ret_type == null) {
+ return false;
+ }
+ }
+ }
+ Gee.List<DataType> resolved_type_args = new ArrayList<DataType> ();
+ foreach (DataType type_arg in ret_type.get_type_arguments ()) {
+ if (type_arg.type_parameter != null && ma != null && ma.inner != null) {
+ resolved_type_args.add (analyzer.get_actual_type (ma.inner.value_type, ma.symbol_reference, type_arg, this));
+ } else {
+ resolved_type_args.add (type_arg);
+ }
+ }
+ ret_type = ret_type.copy ();
+ ret_type.remove_all_type_arguments ();
+ foreach (DataType resolved_type_arg in resolved_type_args) {
+ ret_type.add_type_argument (resolved_type_arg);
+ }
+
+ if (mtype is MethodType) {
+ var m = ((MethodType) mtype).method_symbol;
+ foreach (DataType error_type in m.get_error_types ()) {
+ // ensure we can trace back which expression may throw errors of this type
+ var call_error_type = error_type.copy ();
+ call_error_type.source_reference = source_reference;
+
+ add_error_type (call_error_type);
+ }
+ }
+
+ value_type = ret_type;
+
+ analyzer.check_arguments (this, mtype, params, get_argument_list ());
+
+ return !error;
+ }
}
Modified: trunk/vala/valasemanticanalyzer.vala
==============================================================================
--- trunk/vala/valasemanticanalyzer.vala (original)
+++ trunk/vala/valasemanticanalyzer.vala Wed Nov 5 22:03:37 2008
@@ -41,20 +41,20 @@
public DataType bool_type;
public DataType string_type;
- DataType uchar_type;
- DataType short_type;
- DataType ushort_type;
- DataType int_type;
- DataType uint_type;
- DataType long_type;
- DataType ulong_type;
+ public DataType uchar_type;
+ public DataType short_type;
+ public DataType ushort_type;
+ public DataType int_type;
+ public DataType uint_type;
+ public DataType long_type;
+ public DataType ulong_type;
public DataType size_t_type;
- DataType ssize_t_type;
- DataType int8_type;
- DataType unichar_type;
- DataType double_type;
- DataType type_type;
- Class object_type;
+ public DataType ssize_t_type;
+ public DataType int8_type;
+ public DataType unichar_type;
+ public DataType double_type;
+ public DataType type_type;
+ public Class object_type;
public TypeSymbol initially_unowned_type;
DataType glist_type;
DataType gslist_type;
@@ -69,7 +69,7 @@
// keep replaced alive to make sure they remain valid
// for the whole execution of CodeNode.accept
- Gee.List<CodeNode> replaced_nodes = new ArrayList<CodeNode> ();
+ public Gee.List<CodeNode> replaced_nodes = new ArrayList<CodeNode> ();
public SemanticAnalyzer () {
}
@@ -1550,297 +1550,7 @@
}
public override void visit_invocation_expression (InvocationExpression expr) {
- expr.call.accept (this);
-
- if (expr.call.error) {
- /* if method resolving didn't succeed, skip this check */
- expr.error = true;
- return;
- }
-
- if (expr.call is MemberAccess) {
- var ma = (MemberAccess) expr.call;
- if (ma.prototype_access) {
- expr.error = true;
- Report.error (expr.source_reference, "Access to instance member `%s' denied".printf (expr.call.symbol_reference.get_full_name ()));
- return;
- }
- }
-
- var mtype = expr.call.value_type;
-
- if (mtype is ObjectType) {
- // constructor chain-up
- var cm = find_current_method () as CreationMethod;
- assert (cm != null);
- if (cm.chain_up) {
- expr.error = true;
- Report.error (expr.source_reference, "Multiple constructor calls in the same constructor are not permitted");
- return;
- }
- cm.chain_up = true;
- }
-
- // check for struct construction
- if (expr.call is MemberAccess &&
- ((expr.call.symbol_reference is CreationMethod
- && expr.call.symbol_reference.parent_symbol is Struct)
- || expr.call.symbol_reference is Struct)) {
- var struct_creation_expression = new ObjectCreationExpression ((MemberAccess) expr.call, expr.source_reference);
- struct_creation_expression.struct_creation = true;
- foreach (Expression arg in expr.get_argument_list ()) {
- struct_creation_expression.add_argument (arg);
- }
- struct_creation_expression.target_type = expr.target_type;
- replaced_nodes.add (expr);
- expr.parent_node.replace_expression (expr, struct_creation_expression);
- struct_creation_expression.accept (this);
- return;
- } else if (expr.call is MemberAccess
- && expr.call.symbol_reference is CreationMethod) {
- // constructor chain-up
- var cm = find_current_method () as CreationMethod;
- assert (cm != null);
- if (cm.chain_up) {
- expr.error = true;
- Report.error (expr.source_reference, "Multiple constructor calls in the same constructor are not permitted");
- return;
- }
- cm.chain_up = true;
- }
-
- Gee.List<FormalParameter> params;
-
- if (mtype != null && mtype.is_invokable ()) {
- params = mtype.get_parameters ();
- } else {
- expr.error = true;
- Report.error (expr.source_reference, "invocation not supported in this context");
- return;
- }
-
- Expression last_arg = null;
-
- var args = expr.get_argument_list ();
- Iterator<Expression> arg_it = args.iterator ();
- foreach (FormalParameter param in params) {
- if (param.ellipsis) {
- break;
- }
-
- if (arg_it.next ()) {
- Expression arg = arg_it.get ();
-
- /* store expected type for callback parameters */
- arg.target_type = param.parameter_type;
-
- // resolve generic type parameters
- var ma = expr.call as MemberAccess;
- if (arg.target_type.type_parameter != null) {
- if (ma != null && ma.inner != null) {
- arg.target_type = get_actual_type (ma.inner.value_type, ma.symbol_reference, arg.target_type, arg);
- assert (arg.target_type != null);
- }
- }
-
- last_arg = arg;
- }
- }
-
- // printf arguments
- if (mtype is MethodType && ((MethodType) mtype).method_symbol.printf_format) {
- StringLiteral format_literal = null;
- if (last_arg != null) {
- // use last argument as format string
- format_literal = last_arg as StringLiteral;
- } else {
- // use instance as format string for string.printf (...)
- var ma = expr.call as MemberAccess;
- if (ma != null) {
- format_literal = ma.inner as StringLiteral;
- }
- }
- if (format_literal != null) {
- string format = format_literal.eval ();
-
- bool unsupported_format = false;
-
- weak string format_it = format;
- unichar c = format_it.get_char ();
- while (c != '\0') {
- if (c != '%') {
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- continue;
- }
-
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- // flags
- while (c == '#' || c == '0' || c == '-' || c == ' ' || c == '+') {
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- }
- // field width
- while (c >= '0' && c <= '9') {
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- }
- // precision
- if (c == '.') {
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- while (c >= '0' && c <= '9') {
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- }
- }
- // length modifier
- int length = 0;
- if (c == 'h') {
- length = -1;
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- if (c == 'h') {
- length = -2;
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- }
- } else if (c == 'l') {
- length = 1;
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- } else if (c == 'z') {
- length = 2;
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- }
- // conversion specifier
- DataType param_type = null;
- if (c == 'd' || c == 'i' || c == 'c') {
- // integer
- if (length == -2) {
- param_type = int8_type;
- } else if (length == -1) {
- param_type = short_type;
- } else if (length == 0) {
- param_type = int_type;
- } else if (length == 1) {
- param_type = long_type;
- } else if (length == 2) {
- param_type = ssize_t_type;
- }
- } else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') {
- // unsigned integer
- if (length == -2) {
- param_type = uchar_type;
- } else if (length == -1) {
- param_type = ushort_type;
- } else if (length == 0) {
- param_type = uint_type;
- } else if (length == 1) {
- param_type = ulong_type;
- } else if (length == 2) {
- param_type = size_t_type;
- }
- } else if (c == 'e' || c == 'E' || c == 'f' || c == 'F'
- || c == 'g' || c == 'G' || c == 'a' || c == 'A') {
- // double
- param_type = double_type;
- } else if (c == 's') {
- // string
- param_type = string_type;
- } else if (c == 'p') {
- // pointer
- param_type = new PointerType (new VoidType ());
- } else if (c == '%') {
- // literal %
- } else {
- unsupported_format = true;
- break;
- }
- if (c != '\0') {
- format_it = format_it.next_char ();
- c = format_it.get_char ();
- }
- if (param_type != null) {
- if (arg_it.next ()) {
- Expression arg = arg_it.get ();
-
- arg.target_type = param_type;
- } else {
- Report.error (expr.source_reference, "Too few arguments for specified format");
- return;
- }
- }
- }
- if (!unsupported_format && arg_it.next ()) {
- Report.error (expr.source_reference, "Too many arguments for specified format");
- return;
- }
- }
- }
-
- foreach (Expression arg in expr.get_argument_list ()) {
- arg.accept (this);
- }
-
- DataType ret_type;
-
- ret_type = mtype.get_return_type ();
- params = mtype.get_parameters ();
-
- if (ret_type is VoidType) {
- // void return type
- if (!(expr.parent_node is ExpressionStatement)
- && !(expr.parent_node is ForStatement)
- && !(expr.parent_node is YieldStatement)) {
- // A void method invocation can be in the initializer or
- // iterator of a for statement
- expr.error = true;
- Report.error (expr.source_reference, "invocation of void method not allowed as expression");
- return;
- }
- }
-
- // resolve generic return values
- var ma = expr.call as MemberAccess;
- if (ret_type.type_parameter != null) {
- if (ma != null && ma.inner != null) {
- ret_type = get_actual_type (ma.inner.value_type, ma.symbol_reference, ret_type, expr);
- if (ret_type == null) {
- return;
- }
- }
- }
- Gee.List<DataType> resolved_type_args = new ArrayList<DataType> ();
- foreach (DataType type_arg in ret_type.get_type_arguments ()) {
- if (type_arg.type_parameter != null && ma != null && ma.inner != null) {
- resolved_type_args.add (get_actual_type (ma.inner.value_type, ma.symbol_reference, type_arg, expr));
- } else {
- resolved_type_args.add (type_arg);
- }
- }
- ret_type = ret_type.copy ();
- ret_type.remove_all_type_arguments ();
- foreach (DataType resolved_type_arg in resolved_type_args) {
- ret_type.add_type_argument (resolved_type_arg);
- }
-
- if (mtype is MethodType) {
- var m = ((MethodType) mtype).method_symbol;
- foreach (DataType error_type in m.get_error_types ()) {
- // ensure we can trace back which expression may throw errors of this type
- var call_error_type = error_type.copy ();
- call_error_type.source_reference = expr.source_reference;
-
- expr.add_error_type (call_error_type);
- }
- }
-
- expr.value_type = ret_type;
-
- check_arguments (expr, mtype, params, expr.get_argument_list ());
+ expr.check (this);
}
public bool check_arguments (Expression expr, DataType mtype, Gee.List<FormalParameter> params, Gee.List<Expression> args) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]