internal VList <LNode> Process(VList <LNode> attributes, LNode variableName, bool isPropSetter = false) { return(attributes.Where(attr => { LNode exceptionType = null; var mode = GetContractAttrMode(attr, out exceptionType); if (mode != null) { ProcessAttribute(attr, mode, exceptionType, variableName, isPropSetter); return false; } return true; })); }
[LexicalMacro("notnull T Prop {...}; T this[[requires(expr)] T arg] {...}; " + "T Prop { [requires(expr)] set; }; [ensures(expr)] T Prop {...}; " + "[ensuresOnThrow(expr)] T Prop {...}; [ensuresOnThrow<Exception>(expr)] T Prop {...}", "Generates contract checks in a property. You can apply contract attributes to " + "the property itself, to the getter, to the setter, or all three. When the [requires] " + "or [assert] attributes are applied to the property itself, they are treated as if " + "they were applied to the getter; but when the [ensures], [ensuresAssert], notnull, " + "and [ensuresOnThrow] attributes are applied to the property itself, they are treated " + "as if they were applied to both the getter and the setter separately.", "#property", Mode = MacroMode.Passive | MacroMode.PriorityInternalFallback)] public static LNode ContractsOnProperty(LNode prop, IMacroContext context) { LNode propArgs, oldProp = prop; if (prop.ArgCount == 4) { LNode braces = prop[3]; var oldBraces = braces; var rw = new CodeContractRewriter(prop.Args[0], prop.Args[1], context); prop = ProcessArgContractAttributes(prop, 2, rw); VList <LNode> cAttrs = LNode.List(); prop = prop.WithArgChanged(0, GrabContractAttrs(prop.Args[0], ref cAttrs, ContractAppliesTo.Getter)); prop = GrabContractAttrs(prop, ref cAttrs); LNode getter = null, setter = null; int getterIndex = -1, setterIndex = -1; VList <LNode> getterAttrs = LNode.List(), setterAttrs = LNode.List(); bool isLambdaProperty = !braces.Calls(S.Braces); if (isLambdaProperty) { if (cAttrs.Count == 0) { return(null); } getterAttrs = cAttrs; getter = LNode.Call(CodeSymbols.get, LNode.List(LNode.Call(CodeSymbols.Braces, LNode.List(LNode.Call(CodeSymbols.Return, LNode.List(braces)))).SetStyle(NodeStyle.Statement))).SetStyle(NodeStyle.Special); braces = LNode.Call(CodeSymbols.Braces, LNode.List(getter)).SetStyle(NodeStyle.Statement); getterIndex = 0; } else { for (int i = 0; i < braces.Args.Count; i++) { var part = braces.Args[i]; if (part.Calls(S.get)) { getter = part; getterIndex = i; } if (part.Calls(S.set)) { setter = part; setterIndex = i; } } if (cAttrs.Count != 0) { getterAttrs = cAttrs.Where(a => (PropertyContractInterpretation(a) & ContractAppliesTo.Getter) != 0); setterAttrs = cAttrs.Where(a => (PropertyContractInterpretation(a) & ContractAppliesTo.Setter) != 0); } } var sharedPrependStmts = rw.PrependStmts; if (getter != null) { getter = GrabContractAttrs(getter, ref getterAttrs); rw.Process(getterAttrs, null); rw.PrependStmtsToGetterOrSetter(ref braces, getterIndex, getter); } if (setter != null) { rw.PrependStmts = sharedPrependStmts; setter = GrabContractAttrs(setter, ref setterAttrs); rw.Process(setterAttrs, LNode.Id(CodeSymbols.value), true); rw.PrependStmtsToGetterOrSetter(ref braces, setterIndex, setter); } if (braces == oldBraces) { return(null); } else { return(prop.WithArgChanged(3, braces)); } } return(null); }