private static SyntaxNode GetNegationOfConstantPattern( SyntaxNode pattern, SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal ) { var syntaxFacts = generatorInternal.SyntaxFacts; // If we have `is true/false` just swap that to be `is false/true`. var expression = syntaxFacts.GetExpressionOfConstantPattern(pattern); if (syntaxFacts.IsTrueLiteralExpression(expression)) { return(generatorInternal.ConstantPattern(generator.FalseLiteralExpression())); } if (syntaxFacts.IsFalseLiteralExpression(expression)) { return(generatorInternal.ConstantPattern(generator.TrueLiteralExpression())); } // Otherwise, just negate the entire pattern, we don't have anything else special we can do here. return(generatorInternal.NotPattern(pattern)); }
private TInterpolationSyntax Update( SyntaxGeneratorInternal generator, TInterpolatedStringExpressionSyntax interpolatedString, TInterpolationSyntax interpolation, TExpressionSyntax unwrapped, TExpressionSyntax?alignment, string?formatString ) { var result = WithExpression(interpolation, unwrapped); if (alignment != null) { result = WithAlignmentClause( result, (TInterpolationAlignmentClause)generator.InterpolationAlignmentClause(alignment) ); } if (!string.IsNullOrEmpty(formatString)) { result = WithFormatClause( result, (TInterpolationFormatClause?)generator.InterpolationFormatClause( Escape(interpolatedString, formatString !) ) ); } return(result); }
public static ImmutableArray <SyntaxNode> CreateGetHashCodeStatementsUsingSystemHashCode( this SyntaxGenerator factory, SyntaxGeneratorInternal generatorInternal, INamedTypeSymbol hashCodeType, ImmutableArray <SyntaxNode> memberReferences) { if (memberReferences.Length <= 8) { var statement = factory.ReturnStatement( factory.InvocationExpression( factory.MemberAccessExpression(factory.TypeExpression(hashCodeType), "Combine"), memberReferences)); return(ImmutableArray.Create(statement)); } const string hashName = "hash"; var statements = ArrayBuilder <SyntaxNode> .GetInstance(); statements.Add(factory.SimpleLocalDeclarationStatement(generatorInternal, hashCodeType, hashName, factory.ObjectCreationExpression(hashCodeType))); var localReference = factory.IdentifierName(hashName); foreach (var member in memberReferences) { statements.Add(factory.ExpressionStatement( factory.InvocationExpression( factory.MemberAccessExpression(localReference, "Add"), member))); } statements.Add(factory.ReturnStatement( factory.InvocationExpression( factory.MemberAccessExpression(localReference, "ToHashCode")))); return(statements.ToImmutableAndFree()); }
private static SyntaxNode GetNegationOfBinaryPattern( SyntaxNode pattern, SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, SemanticModel semanticModel, CancellationToken cancellationToken) { // Apply demorgans's law here. // // not (a and b) -> not a or not b // not (a or b) -> not a and not b var syntaxFacts = generatorInternal.SyntaxFacts; syntaxFacts.GetPartsOfBinaryPattern(pattern, out var left, out var operatorToken, out var right); var newLeft = generator.Negate(generatorInternal, left, semanticModel, cancellationToken); var newRight = generator.Negate(generatorInternal, right, semanticModel, cancellationToken); var newPattern = syntaxFacts.IsAndPattern(pattern) ? generatorInternal.OrPattern(newLeft, newRight) : syntaxFacts.IsOrPattern(pattern) ? generatorInternal.AndPattern(newLeft, newRight) : throw ExceptionUtilities.UnexpectedValue(pattern.RawKind); newPattern = newPattern.WithTriviaFrom(pattern); syntaxFacts.GetPartsOfBinaryPattern(newPattern, out _, out var newToken, out _); var newTokenWithTrivia = newToken.WithTriviaFrom(operatorToken); return(newPattern.ReplaceToken(newToken, newTokenWithTrivia)); }
public async Task <Document> FormatNewDocumentAsync(Document document, Document?hintDocument, CodeCleanupOptions options, CancellationToken cancellationToken) { var rootToFormat = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); // Apply file header preferences var fileHeaderTemplate = options.DocumentFormattingOptions.FileHeaderTemplate; if (!string.IsNullOrEmpty(fileHeaderTemplate)) { var newLineTrivia = SyntaxGeneratorInternal.EndOfLine(options.FormattingOptions.NewLine); var rootWithFileHeader = await AbstractFileHeaderCodeFixProvider.GetTransformedSyntaxRootAsync( SyntaxGenerator.SyntaxFacts, FileHeaderHelper, newLineTrivia, document, fileHeaderTemplate, cancellationToken).ConfigureAwait(false); return(document.WithSyntaxRoot(rootWithFileHeader)); } else if (hintDocument is not null) { // If there is no file header preference, see if we can use the one in the hint document var bannerService = hintDocument.GetRequiredLanguageService <IFileBannerFactsService>(); var hintSyntaxRoot = await hintDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var fileBanner = bannerService.GetFileBanner(hintSyntaxRoot); var rootWithBanner = rootToFormat.WithPrependedLeadingTrivia(fileBanner); return(document.WithSyntaxRoot(rootWithBanner)); } return(document); }
private static SyntaxNode SimpleLocalDeclarationStatement( this SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, INamedTypeSymbol namedTypeSymbol, string name, SyntaxNode initializer) { return(generatorInternal.RequiresLocalDeclarationType() ? generator.LocalDeclarationStatement(namedTypeSymbol, name, initializer) : generator.LocalDeclarationStatement(name, initializer)); }
public static SyntaxNode Negate( this SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, SyntaxNode expression, SemanticModel semanticModel, CancellationToken cancellationToken) { return(Negate(generator, generatorInternal, expression, semanticModel, negateBinary: true, cancellationToken)); }
public static SyntaxNode GetDefaultEqualityComparer( this SyntaxGenerator factory, SyntaxGeneratorInternal generatorInternal, Compilation compilation, ITypeSymbol type) { var equalityComparerType = compilation.EqualityComparerOfTType(); var typeExpression = equalityComparerType == null ? factory.GenericName(nameof(EqualityComparer <int>), type) : generatorInternal.Type(equalityComparerType.Construct(type), typeContext: false); return(factory.MemberAccessExpression(typeExpression, factory.IdentifierName(DefaultName))); }
private static SyntaxNode GetNegationOfBinaryExpression( SyntaxNode expressionNode, SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, SemanticModel semanticModel, CancellationToken cancellationToken) { var syntaxFacts = generatorInternal.SyntaxFacts; syntaxFacts.GetPartsOfBinaryExpression(expressionNode, out var leftOperand, out var operatorToken, out var rightOperand); var operation = semanticModel.GetOperation(expressionNode, cancellationToken); if (operation is not IBinaryOperation binaryOperation) { // x is y -> x is not y if (syntaxFacts.IsIsExpression(expressionNode) && syntaxFacts.SupportsNotPattern(semanticModel.SyntaxTree.Options)) { return(generatorInternal.IsPatternExpression(leftOperand, operatorToken, generatorInternal.NotPattern(generatorInternal.TypePattern(rightOperand)))); } // Apply the logical not operator if it is not a binary operation. return(generator.LogicalNotExpression(expressionNode)); } if (!s_negatedBinaryMap.TryGetValue(binaryOperation.OperatorKind, out var negatedKind)) { return(generator.LogicalNotExpression(expressionNode)); } if (binaryOperation.OperatorKind is BinaryOperatorKind.Or or BinaryOperatorKind.And or BinaryOperatorKind.ConditionalAnd or BinaryOperatorKind.ConditionalOr) { leftOperand = generator.Negate(generatorInternal, leftOperand, semanticModel, cancellationToken); rightOperand = generator.Negate(generatorInternal, rightOperand, semanticModel, cancellationToken); } var newBinaryExpressionSyntax = negatedKind is BinaryOperatorKind.Equals or BinaryOperatorKind.NotEquals ? generatorInternal.NegateEquality(generator, expressionNode, leftOperand, negatedKind, rightOperand) : NegateRelational(generator, binaryOperation, leftOperand, negatedKind, rightOperand); newBinaryExpressionSyntax = newBinaryExpressionSyntax.WithTriviaFrom(expressionNode); var newToken = syntaxFacts.GetOperatorTokenOfBinaryExpression(newBinaryExpressionSyntax); return(newBinaryExpressionSyntax.ReplaceToken( newToken, newToken.WithTriviaFrom(operatorToken))); }
private static SyntaxNode GetNegationOfIsPatternExpression( SyntaxNode isExpression, SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, SemanticModel semanticModel, CancellationToken cancellationToken ) { // Don't recurse into patterns if the language doesn't support negated patterns. // Just wrap with a normal '!' expression. var syntaxFacts = generatorInternal.SyntaxFacts; if (syntaxFacts.SupportsNotPattern(semanticModel.SyntaxTree.Options)) { syntaxFacts.GetPartsOfIsPatternExpression( isExpression, out var left, out var isToken, out var pattern ); var negated = generator.Negate( generatorInternal, pattern, semanticModel, cancellationToken ); // Negating the pattern may have formed something illegal. If so, just do a normal `!` negation. if (IsLegalPattern(syntaxFacts, negated, designatorsLegal: true)) { if (syntaxFacts.IsTypePattern(negated)) { // We started with `x is not t`. Unwrap the type pattern for 't' and create a simple `is` binary expr `x is t`. var type = syntaxFacts.GetTypeOfTypePattern(negated); return(generator.IsTypeExpression(left, type)); } else { // Keep this as a normal `is-pattern`, just with the pattern portion negated. return(generatorInternal.IsPatternExpression(left, isToken, negated)); } } } return(generator.LogicalNotExpression(isExpression)); }
public static IMethodSymbol CreateEqualsMethod( this SyntaxGenerator factory, SyntaxGeneratorInternal generatorInternal, Compilation compilation, ParseOptions parseOptions, INamedTypeSymbol containingType, ImmutableArray <ISymbol> symbols, string localNameOpt, SyntaxAnnotation statementAnnotation) { var statements = CreateEqualsMethodStatements( factory, generatorInternal, compilation, parseOptions, containingType, symbols, localNameOpt); statements = statements.SelectAsArray(s => s.WithAdditionalAnnotations(statementAnnotation)); return(CreateEqualsMethod(compilation, statements)); }
private static SyntaxNode GetNegationOfUnaryPattern( SyntaxNode pattern, SyntaxGeneratorInternal generatorInternal, ISyntaxFacts syntaxFacts) { syntaxFacts.GetPartsOfUnaryPattern(pattern, out var opToken, out var subPattern); // not not p -> p if (syntaxFacts.IsNotPattern(pattern)) { return(subPattern.WithPrependedLeadingTrivia(opToken.LeadingTrivia) .WithAdditionalAnnotations(Simplifier.Annotation)); } // If there are other interesting unary patterns in the future, we can support specialized logic for // negating them here. return(generatorInternal.NotPattern(pattern)); }
private IMethodSymbol CreateEqualityOperator( Compilation compilation, SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, ImmutableArray <IParameterSymbol> parameters) { var expression = _containingType.IsValueType ? generator.InvocationExpression( generator.MemberAccessExpression( generator.IdentifierName(LeftName), generator.IdentifierName(EqualsName)), generator.IdentifierName(RightName)) : generator.InvocationExpression( generator.MemberAccessExpression( generator.GetDefaultEqualityComparer(generatorInternal, compilation, _containingType), generator.IdentifierName(EqualsName)), generator.IdentifierName(LeftName), generator.IdentifierName(RightName)); return(CodeGenerationSymbolFactory.CreateOperatorSymbol(
public static ImmutableArray <SyntaxNode> GetGetHashCodeComponents( this SyntaxGenerator factory, SyntaxGeneratorInternal generatorInternal, Compilation compilation, INamedTypeSymbol?containingType, ImmutableArray <ISymbol> members, bool justMemberReference) { var result = ArrayBuilder <SyntaxNode> .GetInstance(); if (containingType != null && GetBaseGetHashCodeMethod(containingType) != null) { result.Add(factory.InvocationExpression( factory.MemberAccessExpression(factory.BaseExpression(), GetHashCodeName))); } foreach (var member in members) { result.Add(GetMemberForGetHashCode(factory, generatorInternal, compilation, member, justMemberReference)); } return(result.ToImmutableAndFree()); }
private static SyntaxNode GetMemberForGetHashCode( SyntaxGenerator factory, SyntaxGeneratorInternal generatorInternal, Compilation compilation, ISymbol member, bool justMemberReference) { var getHashCodeNameExpression = factory.IdentifierName(GetHashCodeName); var thisSymbol = factory.MemberAccessExpression(factory.ThisExpression(), factory.IdentifierName(member.Name)).WithAdditionalAnnotations(Simplification.Simplifier.Annotation); // Caller only wanted the reference to the member, nothing else added. if (justMemberReference) { return(thisSymbol); } if (member.GetSymbolType()?.IsValueType ?? false) { // There is no reason to generate the bulkier syntax of EqualityComparer<>.Default.GetHashCode for value // types. No null check is necessary, and there's no performance advantage on .NET Core for using // EqualityComparer.GetHashCode instead of calling GetHashCode directly. On .NET Framework, using // EqualityComparer.GetHashCode on value types actually performs more poorly. return(factory.InvocationExpression( factory.MemberAccessExpression(thisSymbol, nameof(object.GetHashCode)))); } else { return(factory.InvocationExpression( factory.MemberAccessExpression( GetDefaultEqualityComparer(factory, generatorInternal, compilation, GetType(compilation, member)), getHashCodeNameExpression), thisSymbol)); } }
public static SyntaxNode Negate( this SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, SyntaxNode expression, SemanticModel semanticModel, bool negateBinary, CancellationToken cancellationToken) { var syntaxFacts = generatorInternal.SyntaxFacts; if (syntaxFacts.IsParenthesizedExpression(expression)) { return(generatorInternal.AddParentheses( generator.Negate( generatorInternal, syntaxFacts.GetExpressionOfParenthesizedExpression(expression), semanticModel, negateBinary, cancellationToken)) .WithTriviaFrom(expression)); } if (negateBinary && syntaxFacts.IsBinaryExpression(expression)) { return(GetNegationOfBinaryExpression(expression, generator, generatorInternal, semanticModel, cancellationToken)); } else if (syntaxFacts.IsLiteralExpression(expression)) { return(GetNegationOfLiteralExpression(expression, generator, semanticModel)); } else if (syntaxFacts.IsLogicalNotExpression(expression)) { return(GetNegationOfLogicalNotExpression(expression, syntaxFacts)); } return(generator.LogicalNotExpression(expression)); }
private static TExpressionSyntax MakeRef(SyntaxGeneratorInternal generator, bool isRef, TExpressionSyntax syntaxNode) => isRef ? (TExpressionSyntax)generator.RefExpression(syntaxNode) : syntaxNode;
public static ImmutableArray <SyntaxNode> CreateGetHashCodeMethodStatements( this SyntaxGenerator factory, SyntaxGeneratorInternal generatorInternal, Compilation compilation, INamedTypeSymbol containingType, ImmutableArray <ISymbol> members, bool useInt64) { var components = GetGetHashCodeComponents( factory, compilation, containingType, members, justMemberReference: false); if (components.Length == 0) { return(ImmutableArray.Create(factory.ReturnStatement(factory.LiteralExpression(0)))); } const int hashFactor = -1521134295; var initHash = 0; var baseHashCode = GetBaseGetHashCodeMethod(containingType); if (baseHashCode != null) { initHash = initHash * hashFactor + Hash.GetFNVHashCode(baseHashCode.Name); } foreach (var symbol in members) { initHash = initHash * hashFactor + Hash.GetFNVHashCode(symbol.Name); } if (components.Length == 1 && !useInt64) { // If there's just one value to hash, then we can compute and directly // return it. i.e. The full computation is: // // return initHash * hashfactor + ... // // But as we know the values of initHash and hashFactor we can just compute // is here and directly inject the result value, producing: // // return someHash + this.S1.GetHashCode(); // or var multiplyResult = initHash * hashFactor; return(ImmutableArray.Create(factory.ReturnStatement( factory.AddExpression( CreateLiteralExpression(factory, multiplyResult), components[0])))); } var statements = ArrayBuilder <SyntaxNode> .GetInstance(); // initialize the initial hashCode: // // var hashCode = initialHashCode; const string HashCodeName = "hashCode"; statements.Add(!useInt64 ? factory.SimpleLocalDeclarationStatement(generatorInternal, compilation.GetSpecialType(SpecialType.System_Int32), HashCodeName, CreateLiteralExpression(factory, initHash)) : factory.LocalDeclarationStatement(compilation.GetSpecialType(SpecialType.System_Int64), HashCodeName, CreateLiteralExpression(factory, initHash))); var hashCodeNameExpression = factory.IdentifierName(HashCodeName); // -1521134295 var permuteValue = CreateLiteralExpression(factory, hashFactor); foreach (var component in components) { // hashCode = hashCode * -1521134295 + this.S.GetHashCode(); var rightSide = factory.AddExpression( factory.MultiplyExpression(hashCodeNameExpression, permuteValue), component); if (useInt64) { rightSide = factory.InvocationExpression( factory.MemberAccessExpression(rightSide, GetHashCodeName)); } statements.Add(factory.ExpressionStatement( factory.AssignmentStatement(hashCodeNameExpression, rightSide))); } // And finally, the "return hashCode;" statement. statements.Add(!useInt64 ? factory.ReturnStatement(hashCodeNameExpression) : factory.ReturnStatement( factory.ConvertExpression( compilation.GetSpecialType(SpecialType.System_Int32), hashCodeNameExpression))); return(statements.ToImmutableAndFree()); }
public static SyntaxNode Negate( this SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, SyntaxNode expressionOrPattern, SemanticModel semanticModel, bool negateBinary, CancellationToken cancellationToken) { var syntaxFacts = generatorInternal.SyntaxFacts; if (syntaxFacts.IsParenthesizedExpression(expressionOrPattern)) { return(generatorInternal.AddParentheses( generator.Negate( generatorInternal, syntaxFacts.GetExpressionOfParenthesizedExpression(expressionOrPattern), semanticModel, negateBinary, cancellationToken)) .WithTriviaFrom(expressionOrPattern)); } if (negateBinary && syntaxFacts.IsBinaryExpression(expressionOrPattern)) { return(GetNegationOfBinaryExpression(expressionOrPattern, generator, generatorInternal, semanticModel, cancellationToken)); } if (syntaxFacts.IsLiteralExpression(expressionOrPattern)) { return(GetNegationOfLiteralExpression(expressionOrPattern, generator, semanticModel)); } if (syntaxFacts.IsLogicalNotExpression(expressionOrPattern)) { return(GetNegationOfLogicalNotExpression(expressionOrPattern, syntaxFacts)); } if (negateBinary && syntaxFacts.IsIsPatternExpression(expressionOrPattern)) { return(GetNegationOfIsPatternExpression(expressionOrPattern, generator, generatorInternal, semanticModel, cancellationToken)); } if (syntaxFacts.IsParenthesizedPattern(expressionOrPattern)) { // Push the negation inside the parenthesized pattern. return(generatorInternal.AddParentheses( generator.Negate( generatorInternal, syntaxFacts.GetPatternOfParenthesizedPattern(expressionOrPattern), semanticModel, negateBinary, cancellationToken)) .WithTriviaFrom(expressionOrPattern)); } if (negateBinary && syntaxFacts.IsBinaryPattern(expressionOrPattern)) { return(GetNegationOfBinaryPattern(expressionOrPattern, generator, generatorInternal, semanticModel, cancellationToken)); } if (syntaxFacts.IsConstantPattern(expressionOrPattern)) { return(GetNegationOfConstantPattern(expressionOrPattern, generator, generatorInternal)); } if (syntaxFacts.IsUnaryPattern(expressionOrPattern)) { return(GetNegationOfUnaryPattern(expressionOrPattern, generatorInternal, syntaxFacts)); } // TODO(cyrusn): We could support negating relational patterns in the future. i.e. // // not >= 0 -> < 0 return(syntaxFacts.IsAnyPattern(expressionOrPattern) ? generatorInternal.NotPattern(expressionOrPattern) : generator.LogicalNotExpression(expressionOrPattern)); }
private static SyntaxNode GetNegationOfBinaryExpression( SyntaxNode expressionNode, SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, SemanticModel semanticModel, CancellationToken cancellationToken) { var syntaxFacts = generatorInternal.SyntaxFacts; syntaxFacts.GetPartsOfBinaryExpression(expressionNode, out var leftOperand, out var operatorToken, out var rightOperand); var binaryOperation = semanticModel.GetOperation(expressionNode, cancellationToken) as IBinaryOperation; if (binaryOperation == null) { // x is y -> x is not y if (syntaxFacts.IsIsExpression(expressionNode) && syntaxFacts.SupportsNotPattern(semanticModel.SyntaxTree.Options)) { return(generatorInternal.IsPatternExpression(leftOperand, operatorToken, generatorInternal.NotPattern(generatorInternal.TypePattern(rightOperand)))); } // Apply the logical not operator if it is not a binary operation. return(generator.LogicalNotExpression(expressionNode)); } if (!s_negatedBinaryMap.TryGetValue(binaryOperation.OperatorKind, out var negatedKind)) { return(generator.LogicalNotExpression(expressionNode)); } else { var negateOperands = false; switch (binaryOperation.OperatorKind) { case BinaryOperatorKind.Or: case BinaryOperatorKind.And: case BinaryOperatorKind.ConditionalAnd: case BinaryOperatorKind.ConditionalOr: negateOperands = true; break; } //Workaround for https://github.com/dotnet/roslyn/issues/23956 //Issue to remove this when above is merged if (binaryOperation.OperatorKind == BinaryOperatorKind.Or && syntaxFacts.IsLogicalOrExpression(expressionNode)) { negatedKind = BinaryOperatorKind.ConditionalAnd; } else if (binaryOperation.OperatorKind == BinaryOperatorKind.And && syntaxFacts.IsLogicalAndExpression(expressionNode)) { negatedKind = BinaryOperatorKind.ConditionalOr; } var newLeftOperand = leftOperand; var newRightOperand = rightOperand; if (negateOperands) { newLeftOperand = generator.Negate(generatorInternal, leftOperand, semanticModel, cancellationToken); newRightOperand = generator.Negate(generatorInternal, rightOperand, semanticModel, cancellationToken); } var newBinaryExpressionSyntax = NewBinaryOperation(binaryOperation, newLeftOperand, negatedKind, newRightOperand, generator) .WithTriviaFrom(expressionNode); var newToken = syntaxFacts.GetOperatorTokenOfBinaryExpression(newBinaryExpressionSyntax); var newTokenWithTrivia = newToken.WithTriviaFrom(operatorToken); return(newBinaryExpressionSyntax.ReplaceToken(newToken, newTokenWithTrivia)); } }
private static SyntaxNode GetNegationOfIsPatternExpression(SyntaxNode isExpression, SyntaxGenerator generator, SyntaxGeneratorInternal generatorInternal, SemanticModel semanticModel, CancellationToken cancellationToken) { // Don't recurse into patterns if the language doesn't support negated patterns. // Just wrap with a normal '!' expression. var syntaxFacts = generatorInternal.SyntaxFacts; syntaxFacts.GetPartsOfIsPatternExpression(isExpression, out var left, out var isToken, out var pattern); SyntaxNode?negatedPattern = null; if (syntaxFacts.SupportsNotPattern(semanticModel.SyntaxTree.Options)) { // We do support 'not' patterns. So attempt to push a 'not' pattern into the current is-pattern RHS. negatedPattern = generator.Negate(generatorInternal, pattern, semanticModel, cancellationToken); } else if (syntaxFacts.IsNotPattern(pattern)) { // we don't support 'not' patterns, but we have a 'not' pattern in code. Do a simple unwrapping of it. negatedPattern = GetNegationOfNotPattern(pattern, generator, generatorInternal, syntaxFacts); } // Negating the pattern may have formed something illegal. If so, just do a normal `!` negation. if (negatedPattern != null && IsLegalPattern(syntaxFacts, negatedPattern, designatorsLegal: true)) { if (syntaxFacts.IsTypePattern(negatedPattern)) { // We started with `x is not t`. Unwrap the type pattern for 't' and create a simple `is` binary expr `x is t`. var type = syntaxFacts.GetTypeOfTypePattern(negatedPattern); return(generator.IsTypeExpression(left, type)); } else { // Keep this as a normal `is-pattern`, just with the pattern portion negated. return(generatorInternal.IsPatternExpression(left, isToken, negatedPattern)); } } return(generator.LogicalNotExpression(isExpression)); }