1
+ #nullable enable
1
2
using System ;
2
3
using System . Collections . Generic ;
3
4
using System . Diagnostics . Contracts ;
@@ -20,7 +21,7 @@ public static bool IsExplicitAxiom(this IAttributeBearingDeclaration me) =>
20
21
public record BuiltInAtAttributeArgSyntax (
21
22
string ArgName ,
22
23
Type ArgType , // If null, it means it's not resolved (@Induction and @Trigger)
23
- Expression DefaultValue ) {
24
+ Expression ? DefaultValue ) {
24
25
public Formal ToFormal ( ) {
25
26
Contract . Assert ( ArgType != null ) ;
26
27
return new Formal ( Token . NoToken , ArgName , ArgType , true , false ,
@@ -34,7 +35,7 @@ public record BuiltInAtAttributeSyntax(
34
35
string Name ,
35
36
List < BuiltInAtAttributeArgSyntax > Args ,
36
37
Func < IAttributeBearingDeclaration , bool > CanBeApplied ) {
37
- public BuiltInAtAttributeSyntax WithArg ( String argName , Type argType , Expression defaultValue = null ) {
38
+ public BuiltInAtAttributeSyntax WithArg ( String argName , Type argType , Expression ? defaultValue = null ) {
38
39
var c = new List < BuiltInAtAttributeArgSyntax > ( Args ) {
39
40
new ( argName , argType , defaultValue ) } ;
40
41
return this with { Args = c } ;
@@ -63,9 +64,16 @@ void ObjectInvariant() {
63
64
/*Frozen*/
64
65
public readonly List < Expression > Args ;
65
66
66
- public readonly Attributes Prev ;
67
- public Attributes ( string name , [ Captured ] List < Expression > args , Attributes prev ) : base ( Token . NoToken ) {
68
- Contract . Requires ( name != null ) ;
67
+ public readonly Attributes ? Prev ;
68
+
69
+ [ SyntaxConstructor ]
70
+ public Attributes ( IOrigin origin , string name , List < Expression > args , Attributes ? prev ) : base ( origin ) {
71
+ Name = name ;
72
+ Args = args ;
73
+ Prev = prev ;
74
+ }
75
+
76
+ public Attributes ( string name , [ Captured ] List < Expression > args , Attributes ? prev ) : base ( Token . NoToken ) {
69
77
Contract . Requires ( cce . NonNullElements ( args ) ) ;
70
78
Contract . Requires ( name != UserSuppliedAtAttribute . AtName || this is UserSuppliedAtAttribute ) ;
71
79
Name = name ;
@@ -83,11 +91,11 @@ public override string ToString() {
83
91
}
84
92
}
85
93
86
- public static IEnumerable < Expression > SubExpressions ( Attributes attrs ) {
94
+ public static IEnumerable < Expression > SubExpressions ( Attributes ? attrs ) {
87
95
return attrs . AsEnumerable ( ) . SelectMany ( aa => aa . Args ) ;
88
96
}
89
97
90
- public static bool Contains ( Attributes attrs , string nm ) {
98
+ public static bool Contains ( Attributes ? attrs , string nm ) {
91
99
Contract . Requires ( nm != null ) ;
92
100
return attrs . AsEnumerable ( ) . Any ( aa => aa . Name == nm ) ;
93
101
}
@@ -97,7 +105,7 @@ public static bool Contains(Attributes attrs, string nm) {
97
105
/// attribute.
98
106
/// </summary>
99
107
[ Pure ]
100
- public static Attributes /*?*/ Find ( Attributes attrs , string nm ) {
108
+ public static Attributes ? Find ( Attributes ? attrs , string nm ) {
101
109
Contract . Requires ( nm != null ) ;
102
110
return attrs . AsEnumerable ( ) . FirstOrDefault ( attr => attr . Name == nm ) ;
103
111
}
@@ -111,7 +119,7 @@ public static bool Contains(Attributes attrs, string nm) {
111
119
/// be called very early during resolution before types are available and names have been resolved.
112
120
/// </summary>
113
121
[ Pure ]
114
- public static bool ContainsBool ( Attributes attrs , string nm , ref bool value ) {
122
+ public static bool ContainsBool ( Attributes ? attrs , string nm , ref bool value ) {
115
123
Contract . Requires ( nm != null ) ;
116
124
var attr = attrs . AsEnumerable ( ) . FirstOrDefault ( attr => attr . Name == nm ) ;
117
125
if ( attr == null ) {
@@ -156,7 +164,7 @@ public static bool ContainsBoolAtAnyLevel(MemberDecl decl, string attribName, bo
156
164
/// - if the attribute is {:nm e1,...,en}, then returns (e1,...,en)
157
165
/// Otherwise, returns null.
158
166
/// </summary>
159
- public static List < Expression > FindExpressions ( Attributes attrs , string nm ) {
167
+ public static List < Expression > ? FindExpressions ( Attributes attrs , string nm ) {
160
168
Contract . Requires ( nm != null ) ;
161
169
foreach ( var attr in attrs . AsEnumerable ( ) ) {
162
170
if ( attr . Name == nm ) {
@@ -169,9 +177,8 @@ public static List<Expression> FindExpressions(Attributes attrs, string nm) {
169
177
/// <summary>
170
178
/// Same as FindExpressions, but returns all matches
171
179
/// </summary>
172
- public static List < List < Expression > > FindAllExpressions ( Attributes attrs , string nm ) {
173
- Contract . Requires ( nm != null ) ;
174
- List < List < Expression > > ret = null ;
180
+ public static List < List < Expression > > ? FindAllExpressions ( Attributes ? attrs , string nm ) {
181
+ List < List < Expression > > ? ret = null ;
175
182
for ( ; attrs != null ; attrs = attrs . Prev ) {
176
183
if ( attrs . Name == nm ) {
177
184
ret = ret ?? [ ] ; // Avoid allocating the list in the common case where we don't find nm
@@ -192,11 +199,9 @@ public static List<List<Expression>> FindAllExpressions(Attributes attrs, string
192
199
/// - return false, leave value unmodified, and call reporter with an error string.
193
200
/// </summary>
194
201
public enum MatchingValueOption { Empty , Bool , Int , String , Expression }
195
- public static bool ContainsMatchingValue ( Attributes attrs , string nm , ref object value , IEnumerable < MatchingValueOption > allowed , Action < string > reporter ) {
196
- Contract . Requires ( nm != null ) ;
197
- Contract . Requires ( allowed != null ) ;
198
- Contract . Requires ( reporter != null ) ;
199
- List < Expression > args = FindExpressions ( attrs , nm ) ;
202
+ public static bool ContainsMatchingValue ( Attributes attrs , string nm , ref object value ,
203
+ ISet < MatchingValueOption > allowed , Action < string > reporter ) {
204
+ var args = FindExpressions ( attrs , nm ) ;
200
205
if ( args == null ) {
201
206
return false ;
202
207
} else if ( args . Count == 0 ) {
@@ -207,16 +212,15 @@ public static bool ContainsMatchingValue(Attributes attrs, string nm, ref object
207
212
return false ;
208
213
}
209
214
} else if ( args . Count == 1 ) {
210
- Expression arg = args [ 0 ] ;
211
- StringLiteralExpr stringLiteral = arg as StringLiteralExpr ;
212
- LiteralExpr literal = arg as LiteralExpr ;
213
- if ( literal != null && literal . Value is bool && allowed . Contains ( MatchingValueOption . Bool ) ) {
215
+ var arg = args [ 0 ] ;
216
+ var literal = arg as LiteralExpr ;
217
+ if ( literal is { Value : bool } && allowed . Contains ( MatchingValueOption . Bool ) ) {
214
218
value = literal . Value ;
215
219
return true ;
216
220
} else if ( literal != null && literal . Value is BigInteger && allowed . Contains ( MatchingValueOption . Int ) ) {
217
221
value = literal . Value ;
218
222
return true ;
219
- } else if ( stringLiteral != null && stringLiteral . Value is string && allowed . Contains ( MatchingValueOption . String ) ) {
223
+ } else if ( arg is StringLiteralExpr stringLiteral && stringLiteral . Value is string && allowed . Contains ( MatchingValueOption . String ) ) {
220
224
value = stringLiteral . Value ;
221
225
return true ;
222
226
} else if ( allowed . Contains ( MatchingValueOption . Expression ) ) {
@@ -300,8 +304,7 @@ private static Attributes A1(string name, ActualBindings bindings) {
300
304
301
305
// Given a user-supplied @-attribute, expand it if recognized as builtin to an old-style attribute
302
306
// or mark it as not built-in for later resolution
303
- public static Attributes ExpandAtAttribute ( Program program , UserSuppliedAtAttribute atAttribute , IAttributeBearingDeclaration attributeHost ) {
304
- var toMatch = atAttribute . Arg ;
307
+ public static Attributes ? ExpandAtAttribute ( Program program , UserSuppliedAtAttribute atAttribute , IAttributeBearingDeclaration attributeHost ) {
305
308
var name = atAttribute . UserSuppliedName ;
306
309
var bindings = atAttribute . UserSuppliedPreResolveBindings ;
307
310
@@ -364,7 +367,7 @@ public static Attributes ExpandAtAttribute(Program program, UserSuppliedAtAttrib
364
367
if ( Get ( bindings , 0 , out var lowFuel ) && lowFuel != null ) {
365
368
if ( Get ( bindings , 1 , out var highFuel ) && highFuel != null ) {
366
369
if ( Get ( bindings , 2 , out var functionName ) && IsStringNotEmpty ( functionName ) ) {
367
- return A ( "fuel" , functionName , lowFuel , highFuel ) ;
370
+ return A ( "fuel" , functionName ! , lowFuel , highFuel ) ;
368
371
}
369
372
370
373
return A ( "fuel" , lowFuel , highFuel ) ;
@@ -632,13 +635,13 @@ public static LiteralExpr DefaultInt(int value) {
632
635
return Expression . CreateIntLiteralNonnegative ( Token . NoToken , value ) ;
633
636
}
634
637
635
- private static bool IsStringNotEmpty ( Expression value ) {
638
+ private static bool IsStringNotEmpty ( Expression ? value ) {
636
639
return value is StringLiteralExpr { Value : string and not "" } ;
637
640
}
638
641
639
642
// Given resolved bindings, gets the i-th argument according to the
640
643
// declaration formals order
641
- private static bool Get ( ActualBindings bindings , int i , out Expression expr ) {
644
+ private static bool Get ( ActualBindings bindings , int i , out Expression ? expr ) {
642
645
if ( bindings . Arguments . Count < i + 1 ) {
643
646
expr = null ;
644
647
return false ;
@@ -667,7 +670,7 @@ private static void ResolveLikeDatatypeConstructor(Program program, Formal[] for
667
670
}
668
671
669
672
// Recovers a built-in @-Attribute if it exists
670
- public static bool TryGetBuiltinAtAttribute ( string name , out BuiltInAtAttributeSyntax builtinAtAttribute ) {
673
+ public static bool TryGetBuiltinAtAttribute ( string name , out BuiltInAtAttributeSyntax ? builtinAtAttribute ) {
671
674
return BuiltInAtAttributeDictionary . TryGetValue ( name , out builtinAtAttribute ) ;
672
675
}
673
676
@@ -681,27 +684,27 @@ public static bool TryGetBuiltinAtAttribute(string name, out BuiltInAtAttributeS
681
684
} , b => b ) ;
682
685
683
686
// Overridable method to clone the attribute as if the new attribute was placed after "prev" in the source code
684
- public virtual Attributes CloneAfter ( Attributes prev ) {
687
+ public virtual Attributes CloneAfter ( Attributes ? prev ) {
685
688
return new Attributes ( Name , Args , prev ) ;
686
689
}
687
690
688
691
//////// Helpers for parsing attributes //////////////////
689
692
690
693
// Returns the memory location's attributes content and set the memory location to null (no attributes)
691
- public static Attributes Consume ( ref Attributes tmpStack ) {
694
+ public static Attributes ? Consume ( ref Attributes ? tmpStack ) {
692
695
var result = tmpStack ;
693
696
tmpStack = null ;
694
697
return result ;
695
698
}
696
699
697
700
// Empties the first attribute memory location while prepending its attributes to the second attribute memory location, in the same order
698
- public static void MergeInto ( ref Attributes tmpStack , ref Attributes attributesStack ) {
701
+ public static void MergeInto ( ref Attributes ? tmpStack , ref Attributes ? attributesStack ) {
699
702
MergeIntoReadonly ( tmpStack , ref attributesStack ) ;
700
703
tmpStack = null ;
701
704
}
702
705
703
706
// Prepends the attributes tmpStack before the attributes contained in the memory location attributesStack
704
- private static void MergeIntoReadonly ( Attributes tmpStack , ref Attributes attributesStack ) {
707
+ private static void MergeIntoReadonly ( Attributes ? tmpStack , ref Attributes ? attributesStack ) {
705
708
if ( tmpStack == null ) {
706
709
return ;
707
710
}
@@ -718,7 +721,7 @@ public static class AttributesExtensions {
718
721
/// <summary>
719
722
/// By making this an extension method, it can also be invoked for a null receiver.
720
723
/// </summary>
721
- public static IEnumerable < Attributes > AsEnumerable ( this Attributes attr ) {
724
+ public static IEnumerable < Attributes > AsEnumerable ( this Attributes ? attr ) {
722
725
while ( attr != null ) {
723
726
yield return attr ;
724
727
attr = attr . Prev ;
@@ -731,12 +734,8 @@ public class UserSuppliedAttributes : Attributes {
731
734
public readonly IOrigin OpenBrace ;
732
735
public readonly IOrigin CloseBrace ;
733
736
public bool Recognized ; // set to true to indicate an attribute that is processed by some part of Dafny; this allows it to be colored in the IDE
734
- public UserSuppliedAttributes ( IOrigin origin , IOrigin openBrace , IOrigin closeBrace , List < Expression > args , Attributes prev )
737
+ public UserSuppliedAttributes ( IOrigin origin , IOrigin openBrace , IOrigin closeBrace , List < Expression > args , Attributes ? prev )
735
738
: base ( origin . val , args , prev ) {
736
- Contract . Requires ( origin != null ) ;
737
- Contract . Requires ( openBrace != null ) ;
738
- Contract . Requires ( closeBrace != null ) ;
739
- Contract . Requires ( args != null ) ;
740
739
SetOrigin ( origin ) ;
741
740
OpenBrace = openBrace ;
742
741
CloseBrace = closeBrace ;
@@ -749,22 +748,20 @@ public class UserSuppliedAtAttribute : Attributes {
749
748
public readonly IOrigin AtSign ;
750
749
public bool Builtin ; // set to true to indicate it was recognized as a builtin attribute
751
750
// Otherwise it's a user-defined one and Arg needs to be fully resolved
752
- public UserSuppliedAtAttribute ( IOrigin origin , Expression arg , Attributes prev )
751
+ public UserSuppliedAtAttribute ( IOrigin origin , Expression arg , Attributes ? prev )
753
752
: base ( AtName , [ arg ] , prev ) {
754
- Contract . Requires ( origin != null ) ;
755
753
SetOrigin ( origin ) ;
756
754
this . AtSign = origin ;
757
755
}
758
756
759
757
public Expression Arg => Args [ 0 ] ;
760
758
761
- public override Attributes CloneAfter ( Attributes prev ) {
759
+ public override Attributes CloneAfter ( Attributes ? prev ) {
762
760
return new UserSuppliedAtAttribute ( AtSign , Args [ 0 ] , prev ) ;
763
761
}
764
762
765
763
// Name of this @-Attribute, which is the part right after the @
766
- public string UserSuppliedName =>
767
- GetName ( this ) ;
764
+ public string ? UserSuppliedName => GetName ( this ) ;
768
765
769
766
// Pre-resolved bindings of this @-Attribute
770
767
public ActualBindings UserSuppliedPreResolveBindings =>
@@ -776,7 +773,7 @@ public override Attributes CloneAfter(Attributes prev) {
776
773
GetPreResolveArguments ( this ) ;
777
774
778
775
// Gets the name of an @-attribute. Attributes might be applied.
779
- public static string GetName ( Attributes a ) {
776
+ public static string ? GetName ( Attributes a ) {
780
777
if ( a is UserSuppliedAtAttribute { Arg : ApplySuffix { Lhs : NameSegment { Name : var name } } } ) {
781
778
return name ;
782
779
}
@@ -818,12 +815,12 @@ public static IEnumerable<Expression> GetUserSuppliedArguments(Attributes a) {
818
815
/// A class implementing this interface is one that can carry attributes.
819
816
/// </summary>
820
817
public interface IAttributeBearingDeclaration {
821
- Attributes Attributes { get ; internal set ; }
818
+ Attributes ? Attributes { get ; internal set ; }
822
819
string WhatKind { get ; }
823
820
}
824
821
825
822
public static class AttributeBearingDeclarationExtensions {
826
- public static bool HasUserAttribute ( this IAttributeBearingDeclaration decl , string name , out Attributes attribute ) {
823
+ public static bool HasUserAttribute ( this IAttributeBearingDeclaration decl , string name , out Attributes ? attribute ) {
827
824
if ( Attributes . Find ( decl . Attributes , name ) is UserSuppliedAttributes attr ) {
828
825
attribute = attr ;
829
826
return true ;
0 commit comments