]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Allow unscoped enum values where possible 33c91a04f758c89f0402994a6df894e6c2032def
authorRico Tzschichholz <ricotz@ubuntu.com>
Sun, 19 Nov 2017 19:17:07 +0000 (20:17 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sun, 19 Nov 2017 19:21:30 +0000 (20:21 +0100)
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

tests/Makefile.am
tests/enums/bug666035.vala [new file with mode: 0644]
vala/valabinaryexpression.vala
vala/valamemberaccess.vala
vala/valaswitchlabel.vala

index 86bc2c406d444150bcb8d6279a8cdf281fae5a11..c64a2cd013f0f47612a377100a87ef9d10098dc1 100644 (file)
@@ -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 \
diff --git a/tests/enums/bug666035.vala b/tests/enums/bug666035.vala
new file mode 100644 (file)
index 0000000..16c65d1
--- /dev/null
@@ -0,0 +1,58 @@
+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;
+       }
+}
index 19287da85cfdebe8878cb69a7ca14b465be715f8..afdc75640bd5594b4972e6453fd81e20df2a0d44 100644 (file)
@@ -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;
index c00f5fca55c52305c0b09ba05e6588addf34633d..30143532eb50b2df0d8adcacf4d1585e14d67f26 100644 (file)
@@ -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;
 
index 9468b0ed38bf1767da35b98e4ed3c1acd23dd716..99fbb4a69bdc9f2aebf7eff096c5ea2a444e8c35 100644 (file)
@@ -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");