Commit 33c91a04 authored by Rico Tzschichholz's avatar Rico Tzschichholz

vala: Allow unscoped enum values where possible

If the scope for an enumeration value can be determined from current context
it is possible to omit the enum's scope.

Based on patch by Timo Kluck

https://bugzilla.gnome.org/show_bug.cgi?id=666035
parent 6b656b07
......@@ -120,6 +120,7 @@ TESTS = \
enums/enum_only.vala \
enums/enums.vala \
enums/flags.vala \
enums/bug666035.vala \
enums/bug673879.vala \
enums/bug763831.vala \
enums/bug780050.vala \
......
enum FooEnum {
FOO,
BAR,
MAM;
}
[Flags]
enum FooFlag {
FOO = 1 << 0,
BAR = 1 << 1,
MAM = 1 << 2;
}
struct FooStruct {
public FooEnum f;
}
FooEnum takes_enum (FooEnum foo) {
return foo;
}
FooEnum gives_enum () {
return MAM;
}
FooFlag takes_flag (FooFlag foo) {
return foo;
}
FooFlag gives_flag () {
return MAM | BAR;
}
void main () {
if (takes_enum (BAR) == BAR)
return;
assert (takes_enum (BAR) == BAR);
//TODO assert (MAM == gives_enum ());
assert (takes_flag (BAR | MAM) == (BAR | MAM));
//TODO assert (FOO == takes_flag (BAR & MAM | FOO));
assert (gives_flag () == (BAR | MAM));
FooEnum[] foo_array = { FOO, BAR, FOO };
foo_array[1] = MAM;
assert (foo_array[1] == MAM);
FooStruct foo_struct = { BAR };
assert (foo_struct.f == BAR);
FooEnum foo_enum = BAR;
switch (foo_enum) {
default:
case FOO: assert (false); break;
case BAR: break;
}
}
......@@ -279,6 +279,24 @@ public class Vala.BinaryExpression : Expression {
return true;
}
// enum-type inference
if (target_type != null && target_type.data_type is Enum
&& (operator == BinaryOperator.BITWISE_AND || operator == BinaryOperator.BITWISE_OR)) {
left.target_type = target_type.copy ();
right.target_type = target_type.copy ();
}
left.check (context);
if (left.value_type != null && left.value_type.data_type is Enum
&& (operator == BinaryOperator.EQUALITY || operator == BinaryOperator.INEQUALITY)) {
right.target_type = left.value_type.copy ();
}
right.check (context);
if (right.value_type != null && right.value_type.data_type is Enum
&& (operator == BinaryOperator.EQUALITY || operator == BinaryOperator.INEQUALITY)) {
left.target_type = right.value_type.copy ();
//TODO bug 666035 -- re-check left how?
}
if (!left.check (context) || !right.check (context)) {
/* if there were any errors in inner expressions, skip type check */
error = true;
......
......@@ -452,6 +452,17 @@ public class Vala.MemberAccess : Expression {
}
}
// enum-type inference
if (symbol_reference == null && target_type != null && target_type.data_type is Enum) {
var enum_type = (Enum) target_type.data_type;
foreach (var val in enum_type.get_values ()) {
if (member_name == val.name) {
symbol_reference = val;
break;
}
}
}
if (symbol_reference == null) {
error = true;
......
......@@ -69,9 +69,23 @@ public class Vala.SwitchLabel : CodeNode {
public override bool check (CodeContext context) {
if (expression != null) {
var switch_statement = (SwitchStatement) section.parent_node;
// enum-type inference
var condition_target_type = switch_statement.expression.target_type;
if (expression.symbol_reference == null && condition_target_type != null && condition_target_type.data_type is Enum) {
var enum_type = (Enum) condition_target_type.data_type;
foreach (var val in enum_type.get_values ()) {
if (expression.to_string () == val.name) {
expression.target_type = condition_target_type.copy ();
expression.symbol_reference = val;
break;
}
}
}
expression.check (context);
var switch_statement = (SwitchStatement) section.parent_node;
if (!expression.is_constant ()) {
error = true;
Report.error (expression.source_reference, "Expression must be constant");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment