From 941a08f2da7918b5cf430c4dd1331b53bdd19ac9 Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Thu, 22 Dec 2016 17:13:31 -0800 Subject: [PATCH] Move diagnostic from parser to later phase. --- .../CSharp/Portable/Parser/LanguageParser.cs | 20 ++++++------------- .../Symbols/Source/LocalFunctionSymbol.cs | 2 ++ .../Source/SourceMemberMethodSymbol.cs | 11 +++++++--- .../Symbols/Source/SourceNamedTypeSymbol.cs | 9 +++++++++ .../CSharp/Portable/Symbols/Symbol.cs | 11 ++++++++++ 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs index 3609a69c77f..90ae4d3c511 100644 --- a/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs +++ b/src/Compilers/CSharp/Portable/Parser/LanguageParser.cs @@ -1604,7 +1604,6 @@ private TypeDeclarationSyntax ParseClassOrStructOrInterfaceDeclaration(SyntaxLis var typeParameters = this.ParseTypeParameterList(allowVariance: classOrStructOrInterface.Kind == SyntaxKind.InterfaceKeyword); _termState = saveTerm; - bool hasTypeParams = typeParameters != null; var baseList = this.ParseBaseList(); // Parse class body @@ -1616,7 +1615,7 @@ private TypeDeclarationSyntax ParseClassOrStructOrInterfaceDeclaration(SyntaxLis if (this.CurrentToken.ContextualKind == SyntaxKind.WhereKeyword) { constraints = _pool.Allocate(); - this.ParseTypeParameterConstraintClauses(hasTypeParams, constraints); + this.ParseTypeParameterConstraintClauses(constraints); } var openBrace = this.EatToken(SyntaxKind.OpenBraceToken); @@ -1916,18 +1915,11 @@ private bool IsPossibleTypeParameterConstraintClauseStart() this.PeekToken(2).Kind == SyntaxKind.ColonToken; } - private void ParseTypeParameterConstraintClauses(bool isAllowed, SyntaxListBuilder list) + private void ParseTypeParameterConstraintClauses(SyntaxListBuilder list) { while (this.CurrentToken.ContextualKind == SyntaxKind.WhereKeyword) { - var constraint = this.ParseTypeParameterConstraintClause(); - if (!isAllowed) - { - constraint = this.AddErrorToFirstToken(constraint, ErrorCode.ERR_ConstraintOnlyAllowedOnGenericDecl); - isAllowed = true; // silence any further errors - } - - list.Add(constraint); + list.Add(this.ParseTypeParameterConstraintClause()); } } @@ -2945,7 +2937,7 @@ private bool IsEndOfNameInExplicitInterface() if (this.CurrentToken.ContextualKind == SyntaxKind.WhereKeyword) { constraints = _pool.Allocate(); - this.ParseTypeParameterConstraintClauses(typeParameterList != null, constraints); + this.ParseTypeParameterConstraintClauses(constraints); } else if (this.CurrentToken.Kind == SyntaxKind.ColonToken) { @@ -5103,7 +5095,7 @@ private DelegateDeclarationSyntax ParseDelegateDeclaration(SyntaxListBuilder(); - this.ParseTypeParameterConstraintClauses(typeParameters != null, constraints); + this.ParseTypeParameterConstraintClauses(constraints); } _termState = saveTerm; @@ -8885,7 +8877,7 @@ private static bool IsAccessibilityModifier(SyntaxKind kind) if (this.CurrentToken.ContextualKind == SyntaxKind.WhereKeyword) { constraints = _pool.Allocate(); - this.ParseTypeParameterConstraintClauses(typeParameterListOpt != null, constraints); + this.ParseTypeParameterConstraintClauses(constraints); forceLocalFunc = true; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs index 2fa3d2d142a..81733c69418 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/LocalFunctionSymbol.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; @@ -90,6 +91,7 @@ internal ReturnTypeAndDiagnostics(TypeSymbol returnType, ImmutableArray.Empty; + ReportErrorIfHasConstraints(_syntax.ConstraintClauses, diagnostics); } if (IsExtensionMethod) diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs index 3deb8c961e8..26f7a506927 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberMethodSymbol.cs @@ -95,9 +95,14 @@ internal sealed class SourceMemberMethodSymbol : SourceMethodSymbol this.MakeFlags(methodKind, declarationModifiers, returnsVoid, isExtensionMethod, isMetadataVirtualIgnoringModifiers); - _typeParameters = (syntax.Arity == 0) ? - ImmutableArray.Empty : - MakeTypeParameters(syntax, diagnostics); + _typeParameters = syntax.Arity == 0 + ? ImmutableArray.Empty + : MakeTypeParameters(syntax, diagnostics); + + if (syntax.Arity == 0) + { + ReportErrorIfHasConstraints(syntax.ConstraintClauses, diagnostics); + } bool hasBlockBody = syntax.Body != null; _isExpressionBodied = !hasBlockBody && syntax.ExpressionBody != null; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs index 0b6ef3ad003..c2b65ba772e 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol.cs @@ -118,6 +118,15 @@ private ImmutableArray MakeTypeParameters(DiagnosticBag dia { if (declaration.Arity == 0) { + if (declaration.Kind != DeclarationKind.Enum) + { + foreach (var syntaxRef in this.SyntaxReferences) + { + var constraintClauses = GetConstraintClauses((CSharpSyntaxNode)syntaxRef.GetSyntax()); + ReportErrorIfHasConstraints(constraintClauses, diagnostics); + } + } + return ImmutableArray.Empty; } diff --git a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs index 59cfab664bf..47950af912b 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Symbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Symbol.cs @@ -1089,6 +1089,17 @@ public ImmutableArray ToDisplayParts(SymbolDisplayFormat form return SymbolDisplay.ToMinimalDisplayParts(this, semanticModel, position, format); } + protected static void ReportErrorIfHasConstraints( + SyntaxList constraintClauses, DiagnosticBag diagnostics) + { + if (constraintClauses.Count > 0) + { + diagnostics.Add( + ErrorCode.ERR_ConstraintOnlyAllowedOnGenericDecl, + constraintClauses[0].WhereKeyword.GetLocation()); + } + } + #region ISymbol Members SymbolKind ISymbol.Kind -- GitLab