private void ParseGenericMethodParameterConstraints(SpecSharpGenericMethodParameterDeclaration applicableParameter, TokenSet followers) //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile; { TokenSet constraintStart = Parser.IdentifierOrNonReservedKeyword|Token.Struct|Token.Class|Token.New; if (!constraintStart[this.currentToken]) { this.HandleError(Error.TypeExpected); this.SkipTo(followers); return; } if (this.currentToken == Token.Class) { this.GetNextToken(); applicableParameter.MustBeReferenceType = true; } else if (this.currentToken == Token.Struct) { this.GetNextToken(); applicableParameter.MustBeValueType = true; } while (constraintStart[this.currentToken]) { //^ assume this.currentToken != Token.EndOfFile; if (this.currentToken == Token.Class || this.currentToken == Token.Struct) { this.HandleError(Error.RefValBoundMustBeFirst); this.GetNextToken(); continue; } else if (this.currentToken == Token.New) { this.GetNextToken(); this.Skip(Token.LeftParenthesis); this.Skip(Token.RightParenthesis); applicableParameter.MustHaveDefaultConstructor = true; if (this.currentToken == Token.Comma) { this.HandleError(Error.NewBoundMustBeLast); } break; } applicableParameter.AddConstraint(this.ParseTypeExpression(false, false, constraintStart|Token.Comma|followers)); if (this.currentToken != Token.Comma) break; this.GetNextToken(); } this.SkipTo(followers); }
private void ParseGenericMethodParameterConstraintsClauses(List<Ast.GenericMethodParameterDeclaration> genericMethodParameters, TokenSet followers) // ^ requires forall{Ast.GenericMethodParameterDeclaration genericMethodParameter in genericMethodParameters; genericMethodParameter is SpecSharpGenericMethodParameterDeclaration}; //^ ensures followers[this.currentToken] || this.currentToken == Token.EndOfFile; { while (this.currentToken == Token.Where) { this.GetNextToken(); if (!Parser.IdentifierOrNonReservedKeyword[this.currentToken]) this.HandleError(Error.ExpectedIdentifier); NameDeclaration name = this.ParseNameDeclaration(); SpecSharpGenericMethodParameterDeclaration/*?*/ applicableParameter = null; foreach (Ast.GenericMethodParameterDeclaration genericMethodParameter in genericMethodParameters) if (genericMethodParameter.Name.UniqueKey == name.UniqueKey) { //^ assume genericMethodParameter is SpecSharpGenericMethodParameterDeclaration; //follows from precondition applicableParameter = (SpecSharpGenericMethodParameterDeclaration)genericMethodParameter; break; } if (applicableParameter == null) { this.HandleError(name.SourceLocation, Error.TyVarNotFoundInConstraint); applicableParameter = new SpecSharpGenericMethodParameterDeclaration(null, name, (ushort)genericMethodParameters.Count); } this.Skip(Token.Colon); this.ParseGenericMethodParameterConstraints(applicableParameter, followers|Token.Where); } this.SkipTo(followers); }