[vala/wip/ricotz/lsp-rev: 12/13] vala: Handle unresolved symbols robustly.



commit 37fd4f761b06eca6723513202f29dcfcdf1505d9
Author: Princeton Ferro <princetonferro gmail com>
Date:   Tue Jan 7 17:27:55 2020 -0500

    vala: Handle unresolved symbols robustly.
    
    These changes prevent crashes in later compiler stages when there are
    many unresolved symbols.

 vala/valaarraytype.vala        |  6 +++++-
 vala/valabinaryexpression.vala | 11 +++++++----
 vala/valaclass.vala            |  3 ++-
 vala/valaconstant.vala         |  6 +++---
 vala/valaelementaccess.vala    |  4 +++-
 vala/valagirparser.vala        |  6 ++++++
 vala/valalambdaexpression.vala |  4 ++--
 vala/valamemberaccess.vala     |  3 +++
 vala/valamethodcall.vala       |  7 +++++--
 vala/valaparameter.vala        |  4 ++--
 vala/valathrowstatement.vala   |  8 +++++---
 11 files changed, 43 insertions(+), 19 deletions(-)
---
diff --git a/vala/valaarraytype.vala b/vala/valaarraytype.vala
index bc5eb16d7..24b53c891 100644
--- a/vala/valaarraytype.vala
+++ b/vala/valaarraytype.vala
@@ -106,8 +106,12 @@ public class Vala.ArrayType : ReferenceType {
                return null;
        }
 
-       unowned ArrayLengthField get_length_field () {
+       unowned ArrayLengthField? get_length_field () {
                if (length_field == null) {
+                       if (length_type == null) {
+                               return null;
+                       }
+
                        length_field = new ArrayLengthField (source_reference);
 
                        length_field.access = SymbolAccessibility.PUBLIC;
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index 705635033..f9935cdbd 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -347,8 +347,10 @@ public class Vala.BinaryExpression : Expression {
 
                left.target_type = left.value_type.copy ();
                left.target_type.value_owned = false;
-               right.target_type = right.value_type.copy ();
-               right.target_type.value_owned = false;
+               if (right.value_type != null) {
+                       right.target_type = right.value_type.copy ();
+                       right.target_type.value_owned = false;
+               }
 
                if (operator == BinaryOperator.PLUS
                    && left.value_type.type_symbol == context.analyzer.string_type.type_symbol) {
@@ -564,6 +566,7 @@ public class Vala.BinaryExpression : Expression {
                        break;
                case BinaryOperator.IN:
                        if (left.value_type.compatible (context.analyzer.int_type)
+                           && right.value_type != null
                            && right.value_type.compatible (context.analyzer.int_type)) {
                                // integers or enums
                                left.target_type.nullable = false;
@@ -574,9 +577,9 @@ public class Vala.BinaryExpression : Expression {
                                }
                        } else {
                                // otherwise require a bool contains () method
-                               var contains_method = right.value_type.get_member ("contains") as Method;
+                               var contains_method = (right.value_type != null ? right.value_type.get_member 
("contains") : null) as Method;
                                if (contains_method == null) {
-                                       Report.error (source_reference, "`%s' does not have a `contains' 
method".printf (right.value_type.to_string ()));
+                                       Report.error (source_reference, "`%s' does not have a `contains' 
method".printf (right.value_type != null ? right.value_type.to_string () : "(null)"));
                                        error = true;
                                        return false;
                                }
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index e9312c415..b0d1b0155 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -448,7 +448,8 @@ public class Vala.Class : ObjectTypeSymbol {
                }
 
                foreach (DataType base_type in base_types) {
-                       if (base_type.type_symbol != null && base_type.type_symbol.is_subtype_of (t)) {
+                       if (base_type.type_symbol != null && base_type.type_symbol != this &&
+                               base_type.type_symbol.is_subtype_of (t)) {
                                return true;
                        }
                }
diff --git a/vala/valaconstant.vala b/vala/valaconstant.vala
index 3ff4bf3c4..80872531f 100644
--- a/vala/valaconstant.vala
+++ b/vala/valaconstant.vala
@@ -115,7 +115,7 @@ public class Vala.Constant : Symbol {
 
                type_reference.check (context);
 
-               if (!check_const_type (type_reference, context)) {
+               if (!Constant.check_const_type (type_reference, context)) {
                        error = true;
                        Report.error (source_reference, "`%s' not supported as type for constants".printf 
(type_reference.to_string ()));
                        return false;
@@ -182,13 +182,13 @@ public class Vala.Constant : Symbol {
                return !error;
        }
 
-       bool check_const_type (DataType type, CodeContext context) {
+       static bool check_const_type (DataType type, CodeContext context) {
                if (type is ValueType) {
                        return true;
                } else if (type is ArrayType) {
                        unowned ArrayType array_type = (ArrayType) type;
                        return check_const_type (array_type.element_type, context);
-               } else if (type.type_symbol.is_subtype_of (context.analyzer.string_type.type_symbol)) {
+               } else if (type.type_symbol != null && type.type_symbol.is_subtype_of 
(context.analyzer.string_type.type_symbol)) {
                        return true;
                } else {
                        return false;
diff --git a/vala/valaelementaccess.vala b/vala/valaelementaccess.vala
index 9ecc6c67e..5686d57d3 100644
--- a/vala/valaelementaccess.vala
+++ b/vala/valaelementaccess.vala
@@ -247,7 +247,9 @@ public class Vala.ElementAccess : Expression {
                        }
                }
 
-               value_type.check (context);
+               if (value_type != null) {
+                       value_type.check (context);
+               }
 
                return !error;
        }
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 6719d8e08..7df1e2097 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -1381,6 +1381,12 @@ public class Vala.GirParser : CodeVisitor {
                                continue;
                        }
 
+                       if (ns == null) {
+                               // We should not have a null namespace unless we're in LSP mode.
+                               assert (context.keep_going);
+                               continue;
+                       }
+
                        provided_namespaces.add ("%s-%s".printf (gir_namespace, gir_version));
 
                        var gir_symbol = new UnresolvedSymbol (null, gir_namespace);
diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala
index 4fb7f4564..98c76f6b2 100644
--- a/vala/valalambdaexpression.vala
+++ b/vala/valalambdaexpression.vala
@@ -44,7 +44,7 @@ public class Vala.LambdaExpression : Expression {
        /**
         * The generated method.
         */
-       public Method method { get; set; }
+       public Method? method { get; set; }
 
        private List<Parameter> parameters = new ArrayList<Parameter> ();
 
@@ -249,7 +249,7 @@ public class Vala.LambdaExpression : Expression {
 
        public override void get_used_variables (Collection<Variable> collection) {
                // require captured variables to be initialized
-               if (method.closure) {
+               if (method != null && method.closure) {
                        method.get_captured_variables ((Collection<LocalVariable>) collection);
                }
        }
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 946bd2b0a..3866f6051 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -307,6 +307,9 @@ public class Vala.MemberAccess : Expression {
 
                        if (symbol_reference == null && source_reference != null) {
                                foreach (UsingDirective ns in source_reference.using_directives) {
+                                       if (!(ns.namespace_symbol is Vala.Namespace)) {
+                                               continue;
+                                       }
                                        var local_sym = ns.namespace_symbol.scope.lookup (member_name);
                                        if (local_sym != null) {
                                                if (symbol_reference != null && symbol_reference != 
local_sym) {
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index 150ad7874..9314edb3f 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -163,7 +163,9 @@ public class Vala.MethodCall : Expression {
                        // constructor
                        unowned Class cl = (Class) ((ObjectType) mtype).type_symbol;
                        unowned Method m = cl.default_construction_method;
-                       m.get_error_types (collection, source_reference);
+                       if (m != null) {
+                               m.get_error_types (collection, source_reference);
+                       }
                } else if (mtype is DelegateType) {
                        unowned Delegate d = ((DelegateType) mtype).delegate_symbol;
                        d.get_error_types (collection, source_reference);
@@ -482,7 +484,8 @@ public class Vala.MethodCall : Expression {
                foreach (Expression arg in argument_list) {
                        arg.check (context);
 
-                       if (arg is LambdaExpression && ((LambdaExpression) arg).method.closure) {
+                       if (arg is LambdaExpression && ((LambdaExpression) arg).method != null
+                           && ((LambdaExpression) arg).method.closure) {
                                force_lambda_method_closure = true;
                        }
                }
diff --git a/vala/valaparameter.vala b/vala/valaparameter.vala
index 9c698458b..c16c68da3 100644
--- a/vala/valaparameter.vala
+++ b/vala/valaparameter.vala
@@ -182,8 +182,8 @@ public class Vala.Parameter : Variable {
                                Report.warning (source_reference, "`null' incompatible with parameter type 
`%s'".printf (variable_type.to_string ()));
                        } else if (!(initializer is NullLiteral) && direction == ParameterDirection.OUT) {
                                Report.error (source_reference, "only `null' is allowed as default value for 
out parameters");
-                       } else if (direction == ParameterDirection.IN && !initializer.value_type.compatible 
(variable_type)) {
-                               Report.error (initializer.source_reference, "Cannot convert from `%s' to 
`%s'".printf (initializer.value_type.to_string (), variable_type.to_string ()));
+                       } else if (direction == ParameterDirection.IN && (initializer.value_type == null || 
!initializer.value_type.compatible (variable_type))) {
+                               Report.error (initializer.source_reference, "Cannot convert from `%s' to 
`%s'".printf (initializer.value_type == null ? "(null)" : initializer.value_type.to_string (), 
variable_type.to_string ()));
                        } else if (direction == ParameterDirection.REF) {
                                Report.error (source_reference, "default value not allowed for ref 
parameter");
                        } else if (!initializer.is_accessible (this)) {
diff --git a/vala/valathrowstatement.vala b/vala/valathrowstatement.vala
index 9349b1818..d54d57eab 100644
--- a/vala/valathrowstatement.vala
+++ b/vala/valathrowstatement.vala
@@ -76,9 +76,11 @@ public class Vala.ThrowStatement : CodeNode, Statement {
                if (source_reference == null) {
                        source_reference = this.source_reference;
                }
-               var error_type = error_expression.value_type.copy ();
-               error_type.source_reference = source_reference;
-               collection.add (error_type);
+               if (error_expression.value_type != null) {
+                       var error_type = error_expression.value_type.copy ();
+                       error_type.source_reference = source_reference;
+                       collection.add (error_type);
+               }
        }
 
        public override bool check (CodeContext context) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]