[vala/wip/ricotz/lsp: 9/13] langserver: Handle unresolved symbols robustly.
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/ricotz/lsp: 9/13] langserver: Handle unresolved symbols robustly.
- Date: Thu, 9 Jan 2020 17:53:31 +0000 (UTC)
commit adee6c1d11a1751b2b2302b7642cd809843cb45b
Author: Princeton Ferro <princetonferro gmail com>
Date: Tue Jan 7 17:27:55 2020 -0500
langserver: 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 | 13 ++++++++-----
vala/valaconstant.vala | 6 +++---
vala/valaelementaccess.vala | 4 +++-
vala/valaflowanalyzer.vala | 33 ++++++++++++++++++++++++++++-----
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, 70 insertions(+), 24 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 927ca5413..8396b6947 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -330,8 +330,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) {
@@ -547,7 +549,8 @@ public class Vala.BinaryExpression : Expression {
break;
case BinaryOperator.IN:
if (left.value_type.compatible (context.analyzer.int_type)
- && right.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;
right.target_type.nullable = false;
@@ -557,9 +560,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/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/valaflowanalyzer.vala b/vala/valaflowanalyzer.vala
index 978ab94f8..9cddcd42e 100644
--- a/vala/valaflowanalyzer.vala
+++ b/vala/valaflowanalyzer.vala
@@ -345,12 +345,21 @@ public class Vala.FlowAnalyzer : CodeVisitor {
}
}
- Map<Variable, Set<BasicBlock>> get_assignment_map (List<BasicBlock> block_list, BasicBlock
entry_block) {
+ Map<Variable, Set<BasicBlock>>? get_assignment_map (List<BasicBlock> block_list, BasicBlock
entry_block) {
var map = new HashMap<Variable, Set<BasicBlock>> ();
foreach (BasicBlock block in block_list) {
var defined_variables = new ArrayList<Variable> ();
foreach (CodeNode node in block.get_nodes ()) {
- node.get_defined_variables (defined_variables);
+ var temp_dv = new ArrayList<Variable> ();
+ node.get_defined_variables (temp_dv);
+ foreach (Variable v in temp_dv) {
+ if (v == null) {
+ // Should not have null variable defined when not in LSP mode.
+ assert (context.keep_going);
+ return null;
+ }
+ }
+ defined_variables.add_all (temp_dv);
}
foreach (Variable variable in defined_variables) {
@@ -368,6 +377,10 @@ public class Vala.FlowAnalyzer : CodeVisitor {
void insert_phi_functions (List<BasicBlock> block_list, BasicBlock entry_block) {
var assign = get_assignment_map (block_list, entry_block);
+ if (assign == null) {
+ return;
+ }
+
int counter = 0;
var work_list = new ArrayList<BasicBlock> ();
@@ -476,6 +489,10 @@ public class Vala.FlowAnalyzer : CodeVisitor {
node.get_defined_variables (defined_variables);
foreach (Variable variable in defined_variables) {
+ if (variable == null) {
+ assert (context.keep_going);
+ continue;
+ }
process_assignment (var_map, variable);
}
}
@@ -510,6 +527,11 @@ public class Vala.FlowAnalyzer : CodeVisitor {
node.get_defined_variables (defined_variables);
foreach (Variable variable in defined_variables) {
+ if (variable == null) {
+ // We should not have null variables outside of LSP context.
+ assert (context.keep_going);
+ continue;
+ }
var variable_stack = var_map.get (variable);
variable_stack.remove_at (variable_stack.size - 1);
}
@@ -526,11 +548,12 @@ public class Vala.FlowAnalyzer : CodeVisitor {
var_symbol.single_assignment = false;
}
Variable versioned_var;
+ DataType? var_type = var_symbol.variable_type != null ? var_symbol.variable_type.copy () :
null;
if (var_symbol is LocalVariable) {
- versioned_var = new LocalVariable (var_symbol.variable_type.copy (), var_symbol.name,
null, var_symbol.source_reference);
+ versioned_var = new LocalVariable (var_type, var_symbol.name, null,
var_symbol.source_reference);
} else {
// parameter
- versioned_var = new Parameter (var_symbol.name, var_symbol.variable_type.copy (),
var_symbol.source_reference);
+ versioned_var = new Parameter (var_symbol.name, var_type,
var_symbol.source_reference);
}
variable_stack.add (versioned_var);
return versioned_var;
@@ -987,7 +1010,7 @@ public class Vala.FlowAnalyzer : CodeVisitor {
var error_block = new BasicBlock ();
all_basic_blocks.add (error_block);
- if (catch_clause.error_type != null) {
+ if (catch_clause.error_type != null && !(catch_clause.error_type is InvalidType)) {
if (context.profile == Profile.GOBJECT) {
unowned ErrorType error_type = (ErrorType) catch_clause.error_type;
jump_stack.add (new JumpTarget.error_target (error_block,
catch_clause, catch_clause.error_type.type_symbol as ErrorDomain, error_type.error_code, null));
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 17b41b1e5..a8257fb3b 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 f8b1578b2..0673e0001 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -166,7 +166,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);
@@ -485,7 +487,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 978fec737..7d64c17f6 100644
--- a/vala/valaparameter.vala
+++ b/vala/valaparameter.vala
@@ -176,8 +176,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 ? "(nil)" : 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]