private ConstructorDeclarationSyntax ParseConstructorDeclaration(string typeName, SyntaxListBuilder <AnnotationSyntax> attributes, SyntaxListBuilder modifiers, TypeParameterListSyntax typeParameterList) { var name = this.ParseIdentifierToken(); Debug.Assert(name.ValueText == typeName); var saveTerm = this._termState; this._termState |= TerminatorState.IsEndOfMethodSignature; try { var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: false, allowDefaults: true, allowAttributes: true, allowFieldModifiers: false); JavaThrowsListClauseSyntax throws = this.ParseJavaThrowsListClause(true); ConstructorInitializerSyntax initializer = null; if (this.CurrentToken.Kind == SyntaxKind.ColonToken) { bool isStatic = modifiers != null && modifiers.Any(SyntaxKind.StaticKeyword); initializer = this.ParseConstructorInitializer(name.ValueText, isStatic); } BlockSyntax body; SyntaxToken semicolon; this.ParseBodyOrSemicolon(out body, out semicolon); return(_syntaxFactory.ConstructorDeclaration(attributes, modifiers.ToTokenList(), typeParameterList, name, paramList, throws, initializer, body, semicolon)); } finally { this._termState = saveTerm; } }
private MethodDeclarationSyntax ParseMethodDeclaration( SyntaxListBuilder <AnnotationSyntax> attributes, SyntaxListBuilder modifiers, TypeSyntax type, SyntaxToken identifier, TypeParameterListSyntax typeParameterList, bool isDtor) { // Parse the name (it could be qualified) var saveTerm = this._termState; this._termState |= TerminatorState.IsEndOfMethodSignature; var paramList = this.ParseParenthesizedParameterList(allowThisKeyword: true, allowDefaults: true, allowAttributes: true, allowFieldModifiers: true); JavaThrowsListClauseSyntax throws = this.ParseJavaThrowsListClause(true); if (this.CurrentToken.Kind == SyntaxKind.ColonToken) { // Use else if, rather than if, because if we see both a constructor initializer and a constraint clause, we're too lost to recover. var colonToken = this.CurrentToken; // Set isStatic to false because pretending we're in a static constructor will just result in more errors. ConstructorInitializerSyntax initializer = this.ParseConstructorInitializer(identifier.ValueText, isStatic: false); initializer = this.AddErrorToFirstToken(initializer, ErrorCode.ERR_UnexpectedCharacter, colonToken.Text); //CONSIDER: better error code? paramList = AddTrailingSkippedSyntax(paramList, initializer); // CONSIDER: Parsing an invalid constructor initializer could, conceivably, get us way // off track. If this becomes a problem, an alternative approach would be to generalize // EatTokenWithPrejudice in such a way that we can just skip everything until we recognize // our context again (perhaps an open brace). } this._termState = saveTerm; BlockSyntax body; SyntaxToken semicolon; this.ParseBodyOrSemicolon(out body, out semicolon); return (_syntaxFactory.MethodDeclaration(isDtor ? SyntaxKind.DestructorDeclaration : SyntaxKind.MethodDeclaration, attributes, modifiers.ToTokenList(), typeParameterList, type, identifier, paramList, throws, body, semicolon)); }