]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Move type-argument checks to SemanticAnalyzer
authorRico Tzschichholz <ricotz@ubuntu.com>
Wed, 8 Aug 2018 13:25:51 +0000 (15:25 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 25 Sep 2019 12:17:50 +0000 (14:17 +0200)
and don't apply type-argument check on external symbols.

codegen/valaccodebasemodule.vala
codegen/valaccodemethodcallmodule.vala
codegen/valaccodemethodmodule.vala
vala/valafield.vala
vala/valalocalvariable.vala
vala/valamethod.vala
vala/valaobjectcreationexpression.vala
vala/valaparameter.vala
vala/valaproperty.vala
vala/valasemanticanalyzer.vala

index 7bb4c1861add3cb93f3702589c1973d0548c670f..ff41df47c5c8d0facf20878105dca7fb70a76cb2 100644 (file)
@@ -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;
index 4e5cb10b85fc14b4f5d51fdcc5e4dd128d19ce9d..970606cd68d76450e79e07b4616a53aff8f1b21a 100644 (file)
@@ -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) {
index 4727dfec853e61d7cb7627ba9c64819502ecd5ef..f11e501baedf78a3b673ccab8b08c5b512a1c33a 100644 (file)
@@ -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) {
index 6bd54ff95b376cae725b98a02658c029389d9a08..6e7c6f4713a9fbf4f0ddaad0deb790d7066395be 100644 (file)
@@ -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)) {
index 3a2ecae0155f4e511a50aff55de696126d2962ef..24c2f2b198a0340cf5d471e37290099110d9f23e 100644 (file)
@@ -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:
index 3d7518f6a18c80f25f4cff490ca8e53ebbd828ef..e91da89eb093c4a19bec984c0f55a4fbaf8c7f24 100644 (file)
@@ -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) {
index 5f4fce753eadfe4ea92a84d8aab16b5ea016004e..1f6d335fce6db4473026e70aef82d4af968620d5 100644 (file)
@@ -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);
                }
index 7c13a7c194922be56eab5877a2149e6e69483d9e..19e78a9940458fd88ddca36a0d556f5d56a3176e 100644 (file)
@@ -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;
index cd1bcaff54692fd041759f090779cae2a2abbe86..2ae3d4ace586ec75db3284e639347fe1e3a0cba6 100644 (file)
@@ -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;
index 4a8e777a447faa5f326fb90e1907073f446d9e53..1b40b34ee1d051864c33dedc55c8aeb8c310c35e 100644 (file)
@@ -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 ()));
+               }
+       }
 }