diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2018-08-08 15:25:51 +0200 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2019-09-25 14:17:50 +0200 |
commit | 5182ac26ce718c93925789639f3d89f7ece48650 (patch) | |
tree | 57de40db405adffa1de0892aacfe5e33b4d79d92 | |
parent | f9acb476f06ac4a685c4d2c6470a70bc195df2ba (diff) | |
download | vala-5182ac26ce718c93925789639f3d89f7ece48650.tar.gz |
codegen: Move type-argument checks to SemanticAnalyzer
and don't apply type-argument check on external symbols.
-rw-r--r-- | codegen/valaccodebasemodule.vala | 144 | ||||
-rw-r--r-- | codegen/valaccodemethodcallmodule.vala | 2 | ||||
-rw-r--r-- | codegen/valaccodemethodmodule.vala | 2 | ||||
-rw-r--r-- | vala/valafield.vala | 3 | ||||
-rw-r--r-- | vala/valalocalvariable.vala | 3 | ||||
-rw-r--r-- | vala/valamethod.vala | 3 | ||||
-rw-r--r-- | vala/valaobjectcreationexpression.vala | 7 | ||||
-rw-r--r-- | vala/valaparameter.vala | 4 | ||||
-rw-r--r-- | vala/valaproperty.vala | 3 | ||||
-rw-r--r-- | vala/valasemanticanalyzer.vala | 133 |
10 files changed, 155 insertions, 149 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 7bb4c1861..ff41df47c 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1140,8 +1140,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { push_line (f.source_reference); visit_member (f); - check_type (f.variable_type); - var cl = f.parent_symbol as Class; bool is_gtypeinstance = (cl != null && !cl.is_compact); @@ -1465,17 +1463,9 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { return false; } - public override void visit_formal_parameter (Parameter p) { - if (!p.ellipsis) { - check_type (p.variable_type); - } - } - public override void visit_property (Property prop) { visit_member (prop); - check_type (prop.property_type); - if (prop.get_accessor != null) { prop.get_accessor.accept (this); } @@ -2454,8 +2444,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } public override void visit_local_variable (LocalVariable local) { - check_type (local.variable_type); - /* Declaration */ generate_type_declaration (local.variable_type, cfile); @@ -4546,124 +4534,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } } - bool is_reference_type_argument (DataType type_arg) { - if (type_arg is ErrorType || (type_arg.data_type != null && type_arg.data_type.is_reference_type ())) { - return true; - } else { - return false; - } - } - - bool is_nullable_value_type_argument (DataType type_arg) { - if (type_arg is ValueType && type_arg.nullable) { - return true; - } else { - return false; - } - } - - bool is_signed_integer_type_argument (DataType type_arg) { - var st = type_arg.data_type as Struct; - if (type_arg is EnumValueType) { - return true; - } else if (type_arg.nullable) { - return false; - } else if (st == null) { - return false; - } else if (st.is_subtype_of (bool_type.data_type)) { - return true; - } else if (st.is_subtype_of (char_type.data_type)) { - return true; - } else if (unichar_type != null && st.is_subtype_of (unichar_type.data_type)) { - return true; - } else if (st.is_subtype_of (short_type.data_type)) { - return true; - } else if (st.is_subtype_of (int_type.data_type)) { - return true; - } else if (st.is_subtype_of (long_type.data_type)) { - return true; - } else if (st.is_subtype_of (int8_type.data_type)) { - return true; - } else if (st.is_subtype_of (int16_type.data_type)) { - return true; - } else if (st.is_subtype_of (int32_type.data_type)) { - return true; - } else if (st.is_subtype_of (gtype_type)) { - return true; - } else { - return false; - } - } - - bool is_unsigned_integer_type_argument (DataType type_arg) { - var st = type_arg.data_type as Struct; - if (st == null) { - return false; - } else if (type_arg.nullable) { - return false; - } else if (st.is_subtype_of (uchar_type.data_type)) { - return true; - } else if (st.is_subtype_of (ushort_type.data_type)) { - return true; - } else if (st.is_subtype_of (uint_type.data_type)) { - return true; - } else if (st.is_subtype_of (ulong_type.data_type)) { - return true; - } else if (st.is_subtype_of (uint8_type.data_type)) { - return true; - } else if (st.is_subtype_of (uint16_type.data_type)) { - return true; - } else if (st.is_subtype_of (uint32_type.data_type)) { - return true; - } else { - return false; - } - } - - public void check_type (DataType type) { - var array_type = type as ArrayType; - if (array_type != null) { - check_type (array_type.element_type); - if (array_type.element_type is ArrayType) { - Report.error (type.source_reference, "Stacked arrays are not supported"); - } else if (array_type.element_type is DelegateType) { - var delegate_type = (DelegateType) array_type.element_type; - if (delegate_type.delegate_symbol.has_target) { - Report.error (type.source_reference, "Delegates with target are not supported as array element type"); - } - } - } - foreach (var type_arg in type.get_type_arguments ()) { - check_type (type_arg); - check_type_argument (type_arg); - } - } - - public void check_type_arguments (MemberAccess access) { - foreach (var type_arg in access.get_type_arguments ()) { - check_type (type_arg); - check_type_argument (type_arg); - } - } - - void check_type_argument (DataType type_arg) { - if (type_arg is GenericType - || type_arg is PointerType - || is_reference_type_argument (type_arg) - || is_nullable_value_type_argument (type_arg) - || is_signed_integer_type_argument (type_arg) - || is_unsigned_integer_type_argument (type_arg)) { - // no error - } else if (type_arg is DelegateType) { - var delegate_type = (DelegateType) type_arg; - if (delegate_type.delegate_symbol.has_target) { - Report.error (type_arg.source_reference, "Delegates with target are not supported as generic type arguments"); - } - } else { - Report.error (type_arg.source_reference, "`%s' is not a supported generic type argument, use `?' to box value types".printf (type_arg.to_string ())); - } - } - public virtual void generate_class_declaration (Class cl, CCodeFile decl_space) { if (add_symbol_declaration (decl_space, cl, get_ccode_name (cl))) { return; @@ -4711,8 +4581,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { CCodeExpression instance = null; CCodeExpression creation_expr = null; - check_type (expr.type_reference); - var st = expr.type_reference.data_type as Struct; if ((st != null && (!st.is_simple_type () || get_ccode_name (st) == "va_list")) || expr.get_object_initializer ().size > 0) { // value-type initialization or object creation expression with object initializer @@ -5878,23 +5746,25 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { } public CCodeExpression convert_from_generic_pointer (CCodeExpression cexpr, DataType actual_type) { + unowned SemanticAnalyzer analyzer = context.analyzer; var result = cexpr; - if (is_reference_type_argument (actual_type) || is_nullable_value_type_argument (actual_type)) { + if (analyzer.is_reference_type_argument (actual_type) || analyzer.is_nullable_value_type_argument (actual_type)) { generate_type_declaration (actual_type, cfile); result = new CCodeCastExpression (cexpr, get_ccode_name (actual_type)); - } else if (is_signed_integer_type_argument (actual_type)) { + } else if (analyzer.is_signed_integer_type_argument (actual_type)) { result = new CCodeCastExpression (new CCodeCastExpression (cexpr, "gintptr"), get_ccode_name (actual_type)); - } else if (is_unsigned_integer_type_argument (actual_type)) { + } else if (analyzer.is_unsigned_integer_type_argument (actual_type)) { result = new CCodeCastExpression (new CCodeCastExpression (cexpr, "guintptr"), get_ccode_name (actual_type)); } return result; } public CCodeExpression convert_to_generic_pointer (CCodeExpression cexpr, DataType actual_type) { + unowned SemanticAnalyzer analyzer = context.analyzer; var result = cexpr; - if (is_signed_integer_type_argument (actual_type)) { + if (analyzer.is_signed_integer_type_argument (actual_type)) { result = new CCodeCastExpression (new CCodeCastExpression (cexpr, "gintptr"), "gpointer"); - } else if (is_unsigned_integer_type_argument (actual_type)) { + } else if (analyzer.is_unsigned_integer_type_argument (actual_type)) { result = new CCodeCastExpression (new CCodeCastExpression (cexpr, "guintptr"), "gpointer"); } return result; diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index 4e5cb10b8..970606cd6 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -46,7 +46,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule { m = ((MethodType) itype).method_symbol; if (!get_ccode_simple_generics (m)) { - check_type_arguments (ma); + context.analyzer.check_type_arguments (ma); } if (ma.inner != null && ma.inner.value_type is EnumValueType && ((EnumValueType) ma.inner.value_type).get_to_string_method() == m) { diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index 4727dfec8..f11e501ba 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -327,8 +327,6 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { bool in_gobject_creation_method = false; bool in_fundamental_creation_method = false; - check_type (m.return_type); - bool profile = m.get_attribute ("Profile") != null; if (m is CreationMethod) { diff --git a/vala/valafield.vala b/vala/valafield.vala index 6bd54ff95..6e7c6f471 100644 --- a/vala/valafield.vala +++ b/vala/valafield.vala @@ -99,6 +99,9 @@ public class Vala.Field : Variable, Lockable { } variable_type.check (context); + if (!external_package) { + context.analyzer.check_type (variable_type); + } // check whether field type is at least as accessible as the field if (!context.analyzer.is_type_accessible (this, variable_type)) { diff --git a/vala/valalocalvariable.vala b/vala/valalocalvariable.vala index 3a2ecae01..24c2f2b19 100644 --- a/vala/valalocalvariable.vala +++ b/vala/valalocalvariable.vala @@ -99,6 +99,9 @@ public class Vala.LocalVariable : Variable { return false; } variable_type.check (context); + if (!external_package) { + context.analyzer.check_type (variable_type); + } } // Catch initializer list transformation: diff --git a/vala/valamethod.vala b/vala/valamethod.vala index 3d7518f6a..e91da89eb 100644 --- a/vala/valamethod.vala +++ b/vala/valamethod.vala @@ -785,6 +785,9 @@ public class Vala.Method : Subroutine, Callable { return_type.floating_reference = returns_floating_reference; return_type.check (context); + if (!external_package) { + context.analyzer.check_type (return_type); + } var init_attr = get_attribute ("ModuleInit"); if (init_attr != null) { diff --git a/vala/valaobjectcreationexpression.vala b/vala/valaobjectcreationexpression.vala index 5f4fce753..1f6d335fc 100644 --- a/vala/valaobjectcreationexpression.vala +++ b/vala/valaobjectcreationexpression.vala @@ -188,7 +188,7 @@ public class Vala.ObjectCreationExpression : Expression { } } - TypeSymbol type = null; + TypeSymbol type; if (type_reference == null) { if (member_name == null) { @@ -237,6 +237,7 @@ public class Vala.ObjectCreationExpression : Expression { type = (TypeSymbol) type_sym; type_reference = new StructValueType ((Struct) type); } else if (type_sym is ErrorCode) { + type = (TypeSymbol) type_sym; type_reference = new ErrorType ((ErrorDomain) type_sym.parent_symbol, (ErrorCode) type_sym, source_reference); symbol_reference = type_sym; } else { @@ -486,6 +487,10 @@ public class Vala.ObjectCreationExpression : Expression { } } + if (!type.external_package) { + context.analyzer.check_type (type_reference); + } + foreach (MemberInitializer init in get_object_initializer ()) { context.analyzer.visit_member_initializer (init, type_reference); } diff --git a/vala/valaparameter.vala b/vala/valaparameter.vala index 7c13a7c19..19e78a994 100644 --- a/vala/valaparameter.vala +++ b/vala/valaparameter.vala @@ -186,6 +186,10 @@ public class Vala.Parameter : Variable { } if (!ellipsis) { + if (!external_package) { + context.analyzer.check_type (variable_type); + } + // check whether parameter type is at least as accessible as the method if (!context.analyzer.is_type_accessible (this, variable_type)) { error = true; diff --git a/vala/valaproperty.vala b/vala/valaproperty.vala index cd1bcaff5..2ae3d4ace 100644 --- a/vala/valaproperty.vala +++ b/vala/valaproperty.vala @@ -465,6 +465,9 @@ public class Vala.Property : Symbol, Lockable { } property_type.check (context); + if (!external_package) { + context.analyzer.check_type (property_type); + } if (get_accessor == null && set_accessor == null) { error = true; diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala index 4a8e777a4..1b40b34ee 100644 --- a/vala/valasemanticanalyzer.vala +++ b/vala/valasemanticanalyzer.vala @@ -134,8 +134,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor { public DataType void_type = new VoidType (); public DataType bool_type; - public DataType string_type; - public DataType regex_type; + public DataType char_type; public DataType uchar_type; public DataType short_type; public DataType ushort_type; @@ -143,11 +142,18 @@ public class Vala.SemanticAnalyzer : CodeVisitor { public DataType uint_type; public DataType long_type; public DataType ulong_type; + public DataType int8_type; + public DataType uint8_type; + public DataType int16_type; + public DataType uint16_type; + public DataType int32_type; + public DataType uint32_type; public DataType size_t_type; public DataType ssize_t_type; - public DataType int8_type; public DataType unichar_type; public DataType double_type; + public DataType string_type; + public DataType regex_type; public DataType type_type; public DataType va_list_type; public Class object_type; @@ -180,19 +186,24 @@ public class Vala.SemanticAnalyzer : CodeVisitor { var root_symbol = context.root; bool_type = new BooleanType ((Struct) root_symbol.scope.lookup ("bool")); - string_type = new ObjectType ((Class) root_symbol.scope.lookup ("string")); - int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int")); - uint_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint")); - + char_type = new IntegerType ((Struct) root_symbol.scope.lookup ("char")); uchar_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uchar")); - int8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int8")); short_type = new IntegerType ((Struct) root_symbol.scope.lookup ("short")); ushort_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ushort")); + int_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int")); + uint_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint")); long_type = new IntegerType ((Struct) root_symbol.scope.lookup ("long")); ulong_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ulong")); + int8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int8")); + uint8_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint8")); + int16_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int16")); + uint16_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint16")); + int32_type = new IntegerType ((Struct) root_symbol.scope.lookup ("int32")); + uint32_type = new IntegerType ((Struct) root_symbol.scope.lookup ("uint32")); size_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("size_t")); ssize_t_type = new IntegerType ((Struct) root_symbol.scope.lookup ("ssize_t")); double_type = new FloatingType ((Struct) root_symbol.scope.lookup ("double")); + string_type = new ObjectType ((Class) root_symbol.scope.lookup ("string")); va_list_type = new StructValueType ((Struct) root_symbol.scope.lookup ("va_list")); var unichar_struct = (Struct) root_symbol.scope.lookup ("unichar"); @@ -1187,4 +1198,110 @@ public class Vala.SemanticAnalyzer : CodeVisitor { } return false; } + + public bool is_reference_type_argument (DataType type_arg) { + if (type_arg is ErrorType || (type_arg.data_type != null && type_arg.data_type.is_reference_type ())) { + return true; + } else { + return false; + } + } + + public bool is_nullable_value_type_argument (DataType type_arg) { + if (type_arg is ValueType && type_arg.nullable) { + return true; + } else { + return false; + } + } + + public bool is_signed_integer_type_argument (DataType type_arg) { + var st = type_arg.data_type as Struct; + if (type_arg is EnumValueType) { + return true; + } else if (type_arg.nullable) { + return false; + } else if (st == null) { + return false; + } else if (st.is_subtype_of (bool_type.data_type)) { + return true; + } else if (st.is_subtype_of (char_type.data_type)) { + return true; + } else if (unichar_type != null && st.is_subtype_of (unichar_type.data_type)) { + return true; + } else if (st.is_subtype_of (short_type.data_type)) { + return true; + } else if (st.is_subtype_of (int_type.data_type)) { + return true; + } else if (st.is_subtype_of (long_type.data_type)) { + return true; + } else if (st.is_subtype_of (int8_type.data_type)) { + return true; + } else if (st.is_subtype_of (int16_type.data_type)) { + return true; + } else if (st.is_subtype_of (int32_type.data_type)) { + return true; + } else if (st.is_subtype_of (type_type.data_type)) { + return true; + } else { + return false; + } + } + + public bool is_unsigned_integer_type_argument (DataType type_arg) { + var st = type_arg.data_type as Struct; + if (st == null) { + return false; + } else if (type_arg.nullable) { + return false; + } else if (st.is_subtype_of (uchar_type.data_type)) { + return true; + } else if (st.is_subtype_of (ushort_type.data_type)) { + return true; + } else if (st.is_subtype_of (uint_type.data_type)) { + return true; + } else if (st.is_subtype_of (ulong_type.data_type)) { + return true; + } else if (st.is_subtype_of (uint8_type.data_type)) { + return true; + } else if (st.is_subtype_of (uint16_type.data_type)) { + return true; + } else if (st.is_subtype_of (uint32_type.data_type)) { + return true; + } else { + return false; + } + } + + public void check_type (DataType type) { + foreach (var type_arg in type.get_type_arguments ()) { + check_type (type_arg); + check_type_argument (type_arg); + } + } + + public void check_type_arguments (MemberAccess access) { + foreach (var type_arg in access.get_type_arguments ()) { + check_type (type_arg); + check_type_argument (type_arg); + } + } + + void check_type_argument (DataType type_arg) { + if (type_arg is GenericType + || type_arg is PointerType + || is_reference_type_argument (type_arg) + || is_nullable_value_type_argument (type_arg) + || is_signed_integer_type_argument (type_arg) + || is_unsigned_integer_type_argument (type_arg)) { + // no error + } else if (type_arg is DelegateType) { + var delegate_type = (DelegateType) type_arg; + if (delegate_type.delegate_symbol.has_target) { + Report.error (type_arg.source_reference, "Delegates with target are not supported as generic type arguments"); + } + } else { + Report.error (type_arg.source_reference, "`%s' is not a supported generic type argument, use `?' to box value types".printf (type_arg.to_string ())); + } + } } |