private static void BuildName(NameSyntax nameSyntax, StringBuilder builder, bool includeAlias) { if (nameSyntax.IsKind(SyntaxKind.IdentifierName)) { var identifierNameSyntax = (IdentifierNameSyntax)nameSyntax; builder.Append(identifierNameSyntax.Identifier.ValueText); } else if (nameSyntax.IsKind(SyntaxKind.QualifiedName)) { var qualifiedNameSyntax = (QualifiedNameSyntax)nameSyntax; BuildName(qualifiedNameSyntax.Left, builder, includeAlias); builder.Append(DotChar); BuildName(qualifiedNameSyntax.Right, builder, includeAlias); } else if (nameSyntax.IsKind(SyntaxKind.GenericName)) { var genericNameSyntax = (GenericNameSyntax)nameSyntax; builder.AppendFormat("{0}{1}", genericNameSyntax.Identifier.ValueText, genericNameSyntax.TypeArgumentList.ToString()); } else if (nameSyntax.IsKind(SyntaxKind.AliasQualifiedName)) { var aliasQualifiedNameSyntax = (AliasQualifiedNameSyntax)nameSyntax; if (includeAlias) { builder.Append(aliasQualifiedNameSyntax.Alias.Identifier.ValueText); builder.Append("::"); } builder.Append(aliasQualifiedNameSyntax.Name.Identifier.ValueText); } }
private static void AppendName(StringBuilder builder, NameSyntax name) { if (name.Kind() == SyntaxKind.QualifiedName) { AppendName(builder, ((QualifiedNameSyntax)name).Left); } switch (name.Kind()) { case SyntaxKind.IdentifierName: AppendDotIfNeeded(builder); builder.Append(((IdentifierNameSyntax)name).Identifier.ValueText); break; case SyntaxKind.GenericName: var genericName = (GenericNameSyntax)name; AppendDotIfNeeded(builder); builder.Append(genericName.Identifier.ValueText); AppendArity(builder, genericName.Arity); break; case SyntaxKind.AliasQualifiedName: var aliasQualifiedName = (AliasQualifiedNameSyntax)name; AppendName(builder, aliasQualifiedName.Alias); builder.Append("::"); AppendName(builder, aliasQualifiedName.Name); break; case SyntaxKind.QualifiedName: AppendName(builder, ((QualifiedNameSyntax)name).Right); break; } }
private async Task<IEnumerable<CompletionItem>> GetCompletionsOffOfExplicitInterfaceAsync( Document document, SemanticModel semanticModel, int position, NameSyntax name, CancellationToken cancellationToken) { // Bind the interface name which is to the left of the dot var syntaxTree = semanticModel.SyntaxTree; var nameBinding = semanticModel.GetSymbolInfo(name, cancellationToken); var context = CSharpSyntaxContext.CreateContext(document.Project.Solution.Workspace, semanticModel, position, cancellationToken); var symbol = nameBinding.Symbol as ITypeSymbol; if (symbol == null || symbol.TypeKind != TypeKind.Interface) { return SpecializedCollections.EmptyEnumerable<CompletionItem>(); } var members = semanticModel.LookupSymbols( position: name.SpanStart, container: symbol) .Where(s => !s.IsStatic) .FilterToVisibleAndBrowsableSymbols(document.ShouldHideAdvancedMembers(), semanticModel.Compilation); // We're going to create a entry for each one, including the signature var completions = new List<CompletionItem>(); var signatureDisplayFormat = new SymbolDisplayFormat( genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, memberOptions: SymbolDisplayMemberOptions.IncludeParameters, parameterOptions: SymbolDisplayParameterOptions.IncludeName | SymbolDisplayParameterOptions.IncludeType | SymbolDisplayParameterOptions.IncludeParamsRefOut, miscellaneousOptions: SymbolDisplayMiscellaneousOptions.EscapeKeywordIdentifiers | SymbolDisplayMiscellaneousOptions.UseSpecialTypes); var namePosition = name.SpanStart; var text = await context.SyntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false); var textChangeSpan = CompletionUtilities.GetTextChangeSpan(text, context.Position); foreach (var member in members) { var displayString = member.ToMinimalDisplayString(semanticModel, namePosition, signatureDisplayFormat); var memberCopied = member; var insertionText = displayString; completions.Add(new SymbolCompletionItem( this, displayString, insertionText: insertionText, filterSpan: textChangeSpan, position: position, symbols: new List<ISymbol> { member }, context: context, rules: ItemRules.Instance)); } return completions; }
private bool TryClassifySymbol( NameSyntax name, SymbolInfo symbolInfo, SemanticModel semanticModel, CancellationToken cancellationToken, out IEnumerable<ClassifiedSpan> result) { if (symbolInfo.CandidateReason == CandidateReason.Ambiguous) { return TryClassifyAmbiguousSymbol(name, symbolInfo, semanticModel, cancellationToken, out result); } // Only classify if we get one good symbol back, or if it bound to a constructor symbol with // overload resolution/accessibility errors, or bound to type/constructor and type wasn't creatable. var symbol = TryGetSymbol(name, symbolInfo, semanticModel); ClassifiedSpan classifiedSpan; if (TryClassifySymbol(name, symbol, semanticModel, cancellationToken, out classifiedSpan)) { result = SpecializedCollections.SingletonEnumerable(classifiedSpan); return true; } result = null; return false; }
private static bool IsNamespaceName(NameSyntax name) { while (name.Parent is NameSyntax) { name = (NameSyntax)name.Parent; } return name.IsParentKind(SyntaxKind.NamespaceDeclaration); }
public DeltaGen(CodeGen generator) : base(generator) { var recursiveType = this.applyTo.RecursiveTypeFromFamily; if (!recursiveType.IsDefault) { this.changedPropertiesEnumTypeName = SyntaxFactory.IdentifierName(recursiveType.TypeSymbol.Name + "ChangedProperties"); this.diffGramTypeSyntax = SyntaxFactory.QualifiedName(recursiveType.TypeSyntax, DiffGramTypeName); this.recursiveDiffingType = SyntaxFactory.QualifiedName( SyntaxFactory.IdentifierName(nameof(ImmutableObjectGraph)), SyntaxFactory.GenericName(nameof(ImmutableObjectGraph.IRecursiveDiffingType<uint, uint>)) .AddTypeArgumentListArguments( this.changedPropertiesEnumTypeName, this.diffGramTypeSyntax)); } }
private Document IntroduceQueryLocalForSingleOccurrence( SemanticDocument document, ExpressionSyntax expression, NameSyntax newLocalName, LetClauseSyntax letClause, bool allOccurrences, CancellationToken cancellationToken) { var oldClause = expression.GetAncestors<SyntaxNode>().First(IsAnyQueryClause); var newClause = Rewrite( document, expression, newLocalName, document, oldClause, allOccurrences, cancellationToken); var oldQuery = (QueryBodySyntax)oldClause.Parent; var newQuery = GetNewQuery(oldQuery, oldClause, newClause, letClause); var newRoot = document.Root.ReplaceNode(oldQuery, newQuery); return document.Document.WithSyntaxRoot(newRoot); }
private static ISymbol TryGetSymbol(NameSyntax name, SymbolInfo symbolInfo, SemanticModel semanticModel) { if (symbolInfo.Symbol == null && symbolInfo.CandidateSymbols.Length > 0) { var firstSymbol = symbolInfo.CandidateSymbols[0]; switch (symbolInfo.CandidateReason) { case CandidateReason.NotAValue: return firstSymbol; case CandidateReason.NotCreatable: // We want to color types even if they can't be constructed. if (firstSymbol.IsConstructor() || firstSymbol is ITypeSymbol) { return firstSymbol; } break; case CandidateReason.OverloadResolutionFailure: // If we couldn't bind to a constructor, still classify the type. if (firstSymbol.IsConstructor()) { return firstSymbol; } break; case CandidateReason.Inaccessible: // If a constructor wasn't accessible, still classify the type if it's accessible. if (firstSymbol.IsConstructor() && semanticModel.IsAccessible(name.SpanStart, firstSymbol.ContainingType)) { return firstSymbol; } break; } } return symbolInfo.Symbol; }
private IEnumerable<ClassifiedSpan> ClassifyTypeSyntax( NameSyntax name, SemanticModel semanticModel, CancellationToken cancellationToken) { if (!IsNamespaceName(name)) { var symbolInfo = semanticModel.GetSymbolInfo(name, cancellationToken); IEnumerable<ClassifiedSpan> result; if (TryClassifySymbol(name, symbolInfo, semanticModel, cancellationToken, out result) || TryClassifyFromIdentifier(name, symbolInfo, out result) || TryClassifyValueIdentifier(name, symbolInfo, out result)) { return result; } } return null; }
public FastSpineGen(CodeGen generator) : base(generator) { if (this.applyTo.IsRecursive || this.applyTo.IsRecursiveParentOrDerivative) { var keyValuePairType = SyntaxFactory.ParseTypeName( string.Format( CultureInfo.InvariantCulture, "System.Collections.Generic.KeyValuePair<{1}, {0}>", IdentityFieldTypeSyntax, this.applyTo.RecursiveTypeFromFamily.TypeSyntax)); this.lookupTableType = SyntaxFactory.ParseTypeName( string.Format( CultureInfo.InvariantCulture, "System.Collections.Immutable.ImmutableDictionary<{0}, {1}>", IdentityFieldTypeSyntax, keyValuePairType)); this.IRecursiveParentWithChildReplacementType = SyntaxFactory.QualifiedName( SyntaxFactory.IdentifierName(nameof(ImmutableObjectGraph)), SyntaxFactory.GenericName(nameof(IRecursiveParentWithChildReplacement<IRecursiveType>)) .AddTypeArgumentListArguments(this.applyTo.RecursiveType.TypeSyntax)); } }
private static void CheckNameSyntax(SyntaxNodeAnalysisContext context, NameSyntax nameSyntax) { if (nameSyntax == null || nameSyntax.IsMissing) { return; } QualifiedNameSyntax qualifiedNameSyntax = nameSyntax as QualifiedNameSyntax; if (qualifiedNameSyntax != null) { CheckNameSyntax(context, qualifiedNameSyntax.Left); CheckNameSyntax(context, qualifiedNameSyntax.Right); return; } SimpleNameSyntax simpleNameSyntax = nameSyntax as SimpleNameSyntax; if (simpleNameSyntax != null) { CheckElementNameToken(context, simpleNameSyntax.Identifier); return; } // TODO: any other cases? }
private static ImmutableArray<ISymbol> GetSymbolsOffOfName( CSharpSyntaxContext context, NameSyntax name, CancellationToken cancellationToken) { // Check if we're in an interesting situation like this: // // int i = 5; // i. // <-- here // List<string> ml = new List<string>(); // The problem is that "i.List<string>" gets parsed as a type. In this case we need to // try binding again as if "i" is an expression and not a type. In order to do that, we // need to speculate as to what 'i' meant if it wasn't part of a local declaration's // type. if (name.IsFoundUnder<LocalDeclarationStatementSyntax>(d => d.Declaration.Type)) { var speculativeBinding = context.SemanticModel.GetSpeculativeSymbolInfo(name.SpanStart, name, SpeculativeBindingOption.BindAsExpression); var container = context.SemanticModel.GetSpeculativeTypeInfo(name.SpanStart, name, SpeculativeBindingOption.BindAsExpression).Type; return GetSymbolsOffOfBoundExpression(context, name, name, speculativeBinding, container, cancellationToken); } // We're in a name-only context, since if we were an expression we'd be a // MemberAccessExpressionSyntax. Thus, let's do other namespaces and types. var nameBinding = context.SemanticModel.GetSymbolInfo(name, cancellationToken); var symbol = nameBinding.Symbol as INamespaceOrTypeSymbol; if (symbol != null) { if (context.IsNameOfContext) { return context.SemanticModel.LookupSymbols(position: name.SpanStart, container: symbol); } var symbols = context.SemanticModel.LookupNamespacesAndTypes( position: name.SpanStart, container: symbol); if (context.IsNamespaceDeclarationNameContext) { var declarationSyntax = name.GetAncestorOrThis<NamespaceDeclarationSyntax>(); return symbols.WhereAsArray(s => IsNonIntersectingNamespace(s, declarationSyntax)); } // Filter the types when in a using directive, but not an alias. // // Cases: // using | -- Show namespaces // using A.| -- Show namespaces // using static | -- Show namespace and types // using A = B.| -- Show namespace and types var usingDirective = name.GetAncestorOrThis<UsingDirectiveSyntax>(); if (usingDirective != null && usingDirective.Alias == null) { if (usingDirective.StaticKeyword.IsKind(SyntaxKind.StaticKeyword)) { return symbols.WhereAsArray(s => !s.IsDelegateType() && !s.IsInterfaceType()); } else { symbols = symbols.WhereAsArray(s => s.IsNamespace()); } } if (symbols.Any()) { return symbols; } } return ImmutableArray<ISymbol>.Empty; }
private Symbol GetDeclaredMember(NamespaceOrTypeSymbol container, TextSpan declarationSpan, NameSyntax name) { switch (name.Kind()) { case SyntaxKind.GenericName: case SyntaxKind.IdentifierName: return GetDeclaredMember(container, declarationSpan, ((SimpleNameSyntax)name).Identifier.ValueText); case SyntaxKind.QualifiedName: var qn = (QualifiedNameSyntax)name; var left = GetDeclaredMember(container, declarationSpan, qn.Left) as NamespaceOrTypeSymbol; Debug.Assert((object)left != null); return GetDeclaredMember(left, declarationSpan, qn.Right); case SyntaxKind.AliasQualifiedName: // this is not supposed to happen, but we allow for errors don't we! var an = (AliasQualifiedNameSyntax)name; return GetDeclaredMember(container, declarationSpan, an.Name); default: throw ExceptionUtilities.UnexpectedValue(name.Kind()); } }
bool IsRewritableMethod(NameSyntax methodNameSyntax) { var symbol = model.GetSymbolInfo(methodNameSyntax).Symbol as IMethodSymbol; return symbol != null && symbol.HasAttribute<MetaRewriteTypeArgsAttribute>(model.Compilation); }
private static bool PreferPredefinedTypeKeywordInDeclarations(NameSyntax name, OptionSet optionSet, SemanticModel semanticModel) { return !IsInMemberAccessContext(name) && !InsideCrefReference(name) && !InsideNameOfExpression(name, semanticModel) && SimplificationHelpers.PreferPredefinedTypeKeywordInDeclarations(optionSet, semanticModel.Language); }
private static bool IsInScriptClass(SemanticModel model, NameSyntax name) { var symbol = model.GetSymbolInfo(name).Symbol as INamedTypeSymbol; while (symbol != null) { if (symbol.IsScriptClass) { return true; } symbol = symbol.ContainingType; } return false; }
private static bool IsQualifiedNameInUsingDirective(SemanticModel model, NameSyntax name, TypeSyntax reducedName) { while (name.IsLeftSideOfQualifiedName()) { name = (NameSyntax)name.Parent; } if (name.IsParentKind(SyntaxKind.UsingDirective) && ((UsingDirectiveSyntax)name.Parent).Alias == null) { // We're a qualified name in a using. We don't want to reduce this name as people like // fully qualified names in usings so they can properly tell what the name is resolving // to. // However, if this name is actually referencing the special Script class, then we do // want to allow that to be reduced. return !IsInScriptClass(model, name); } return false; }
private bool TryClassifyFromIdentifier( NameSyntax name, SymbolInfo symbolInfo, out IEnumerable<ClassifiedSpan> result) { // Okay - it wasn't a type. If the syntax matches "var q = from" or "q = from", and from // doesn't bind to anything then optimistically color from as a keyword. var identifierName = name as IdentifierNameSyntax; if (identifierName != null && identifierName.Identifier.HasMatchingText(SyntaxKind.FromKeyword) && symbolInfo.Symbol == null) { var token = identifierName.Identifier; if (identifierName.IsRightSideOfAnyAssignExpression() || identifierName.IsVariableDeclaratorValue()) { result = SpecializedCollections.SingletonEnumerable( new ClassifiedSpan(token.Span, ClassificationTypeNames.Keyword)); return true; } } result = null; return false; }
private static bool PreferPredefinedTypeKeywordInDeclarations(NameSyntax name, OptionSet optionSet, SemanticModel semanticModel) { return (name.Parent != null) && !(name.Parent is MemberAccessExpressionSyntax) && !InsideCrefReference(name) && !InsideNameOfExpression(name, semanticModel) && optionSet.GetOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration, LanguageNames.CSharp); }
private bool TryClassifySymbol( NameSyntax name, ISymbol symbol, SemanticModel semanticModel, CancellationToken cancellationToken, out ClassifiedSpan classifiedSpan) { if (symbol != null) { // see through using aliases if (symbol.Kind == SymbolKind.Alias) { symbol = (symbol as IAliasSymbol).Target; } else if (symbol.IsConstructor() && name.IsParentKind(SyntaxKind.Attribute)) { symbol = symbol.ContainingType; } } if (name.IsVar && IsInVarContext(name)) { var alias = semanticModel.GetAliasInfo(name, cancellationToken); if (alias == null || alias.Name != "var") { if (!IsSymbolCalledVar(symbol)) { // We bound to a symbol. If we bound to a symbol called "var" then we want to // classify this appropriately as a type. Otherwise, we want to classify this as // a keyword. classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword); return true; } } } if (symbol != null) { // Use .Equals since we can't rely on object identity for constructed types. if (symbol is ITypeSymbol) { var classification = GetClassificationForType((ITypeSymbol)symbol); if (classification != null) { var token = name.GetNameToken(); classifiedSpan = new ClassifiedSpan(token.Span, classification); return true; } } } classifiedSpan = default(ClassifiedSpan); return false; }
private static bool TryReduceAttributeSuffix( NameSyntax name, SyntaxToken identifierToken, SemanticModel semanticModel, out TypeSyntax replacementNode, out TextSpan issueSpan, CancellationToken cancellationToken) { issueSpan = default(TextSpan); replacementNode = default(TypeSyntax); // we can try to remove the Attribute suffix if this is the attribute name if (SyntaxFacts.IsAttributeName(name)) { if (name.Parent.Kind() == SyntaxKind.Attribute || name.IsRightSideOfDotOrColonColon()) { const string AttributeName = "Attribute"; // an attribute that should keep it (unnecessary "Attribute" suffix should be annotated with a DontSimplifyAnnotation if (identifierToken.ValueText != AttributeName && identifierToken.ValueText.EndsWith(AttributeName, StringComparison.Ordinal) && !identifierToken.HasAnnotation(SimplificationHelpers.DontSimplifyAnnotation)) { // weird. the semantic model is able to bind attribute syntax like "[as()]" although it's not valid code. // so we need another check for keywords manually. var newAttributeName = identifierToken.ValueText.Substring(0, identifierToken.ValueText.Length - 9); if (SyntaxFacts.GetKeywordKind(newAttributeName) != SyntaxKind.None) { return false; } // if this attribute name in source contained unicode escaping, we will loose it now // because there is no easy way to determine the substring from identifier->ToString() // which would be needed to pass to SyntaxFactory.Identifier // The result is an unescaped unicode character in source. // once we remove the Attribute suffix, we can't use an escaped identifier var newIdentifierToken = identifierToken.CopyAnnotationsTo( SyntaxFactory.Identifier( identifierToken.LeadingTrivia, newAttributeName, identifierToken.TrailingTrivia)); replacementNode = SyntaxFactory.IdentifierName(newIdentifierToken) .WithLeadingTrivia(name.GetLeadingTrivia()); issueSpan = new TextSpan(identifierToken.Span.End - 9, 9); return true; } } } return false; }
private bool TryClassifyNameOfIdentifier(NameSyntax name, SymbolInfo symbolInfo, out IEnumerable<ClassifiedSpan> result) { var identifierName = name as IdentifierNameSyntax; if (identifierName != null && identifierName.Identifier.IsKindOrHasMatchingText(SyntaxKind.NameOfKeyword) && symbolInfo.Symbol == null && !symbolInfo.CandidateSymbols.Any()) { result = SpecializedCollections.SingletonEnumerable(new ClassifiedSpan(identifierName.Identifier.Span, ClassificationTypeNames.Keyword)); return true; } result = null; return false; }
private bool TryClassifyValueIdentifier( NameSyntax name, SymbolInfo symbolInfo, out IEnumerable<ClassifiedSpan> result) { var identifierName = name as IdentifierNameSyntax; if (symbolInfo.Symbol.IsImplicitValueParameter()) { result = SpecializedCollections.SingletonEnumerable( new ClassifiedSpan(identifierName.Identifier.Span, ClassificationTypeNames.Keyword)); return true; } result = null; return false; }
private static bool CanSimplifyNullable(INamedTypeSymbol type, NameSyntax name, SemanticModel semanticModel) { if (!type.IsNullable()) { return false; } if (type.IsUnboundGenericType) { // Don't simplify unbound generic type "Nullable<>". return false; } if (InsideNameOfExpression(name, semanticModel)) { // Nullable<T> can't be simplified to T? in nameof expressions. return false; } if (!InsideCrefReference(name)) { // Nullable<T> can always be simplified to T? outside crefs. return true; } // Inside crefs, if the T in this Nullable{T} is being declared right here // then this Nullable{T} is not a constructed generic type and we should // not offer to simplify this to T?. // // For example, we should not offer the simplification in the following cases where // T does not bind to an existing type / type parameter in the user's code. // - <see cref="Nullable{T}"/> // - <see cref="System.Nullable{T}.Value"/> // // And we should offer the simplification in the following cases where SomeType and // SomeMethod bind to a type and method declared elsewhere in the users code. // - <see cref="SomeType.SomeMethod(Nullable{SomeType})"/> var argument = type.TypeArguments.SingleOrDefault(); if (argument == null || argument.IsErrorType()) { return false; } var argumentDecl = argument.DeclaringSyntaxReferences.FirstOrDefault(); if (argumentDecl == null) { // The type argument is a type from metadata - so this is a constructed generic nullable type that can be simplified (e.g. Nullable(Of Integer)). return true; } return !name.Span.Contains(argumentDecl.Span); }
private static bool CanReplaceWithPredefinedTypeKeywordInContext( NameSyntax name, SemanticModel semanticModel, out TypeSyntax replacementNode, ref TextSpan issueSpan, SyntaxKind keywordKind, string codeStyleOptionName, CancellationToken cancellationToken) { replacementNode = CreatePredefinedTypeSyntax(name, keywordKind); issueSpan = name.Span; // we want to show the whole name expression as unnecessary var canReduce = name.CanReplaceWithReducedNameInContext(replacementNode, semanticModel, cancellationToken); if (canReduce) { replacementNode = replacementNode.WithAdditionalAnnotations(new SyntaxAnnotation(codeStyleOptionName)); } return canReduce; }
private static bool CanReplaceWithPredefinedTypeKeywordInContext(NameSyntax name, SemanticModel semanticModel, out TypeSyntax replacementNode, ref TextSpan issueSpan, SyntaxKind keywordKind, CancellationToken cancellationToken) { replacementNode = CreatePredefinedTypeSyntax(name, keywordKind); issueSpan = name.Span; // we want to show the whole name expression as unnecessary return name.CanReplaceWithReducedNameInContext(replacementNode, semanticModel, cancellationToken); }
private bool IsInVarContext(NameSyntax name) { return name.CheckParent<VariableDeclarationSyntax>(v => v.Type == name) || name.CheckParent<ForEachStatementSyntax>(f => f.Type == name) || name.CheckParent<TypedVariableComponentSyntax>(f => f.Type == name); }
private static bool ContainsOpenName(NameSyntax name) { if (name is QualifiedNameSyntax) { var qualifiedName = (QualifiedNameSyntax)name; return ContainsOpenName(qualifiedName.Left) || ContainsOpenName(qualifiedName.Right); } else if (name is GenericNameSyntax) { return ((GenericNameSyntax)name).IsUnboundGenericName; } else { return false; } }
private bool TryClassifyAmbiguousSymbol( NameSyntax name, SymbolInfo symbolInfo, SemanticModel semanticModel, CancellationToken cancellationToken, out IEnumerable<ClassifiedSpan> result) { // If everything classifies the same way, then just pick that classification. var set = new HashSet<ClassifiedSpan>(); foreach (var symbol in symbolInfo.CandidateSymbols) { ClassifiedSpan classifiedSpan; if (TryClassifySymbol(name, symbol, semanticModel, cancellationToken, out classifiedSpan)) { set.Add(classifiedSpan); } } if (set.Count == 1) { result = SpecializedCollections.SingletonEnumerable(set.First()); return true; } result = null; return false; }
private bool CompareNames(NameSyntax oldName, NameSyntax newName) { if (oldName.Kind() != newName.Kind()) { return false; } switch (oldName.Kind()) { case SyntaxKind.IdentifierName: var oldIdentifierName = (IdentifierNameSyntax)oldName; var newIdentifierName = (IdentifierNameSyntax)newName; return StringComparer.Ordinal.Equals(oldIdentifierName.Identifier.ToString(), newIdentifierName.Identifier.ToString()); case SyntaxKind.QualifiedName: var oldQualifiedName = (QualifiedNameSyntax)oldName; var newQualifiedName = (QualifiedNameSyntax)newName; return CompareNames(oldQualifiedName.Left, newQualifiedName.Left) && CompareNames(oldQualifiedName.Right, oldQualifiedName.Right); case SyntaxKind.GenericName: var oldGenericName = (GenericNameSyntax)oldName; var newGenericName = (GenericNameSyntax)newName; if (!StringComparer.Ordinal.Equals(oldGenericName.Identifier.ToString(), newGenericName.Identifier.ToString())) { return false; } if (oldGenericName.Arity != newGenericName.Arity) { return false; } for (int i = 0; i < oldGenericName.Arity; i++) { if (!CompareTypes(oldGenericName.TypeArgumentList.Arguments[i], newGenericName.TypeArgumentList.Arguments[i])) { return false; } } return true; case SyntaxKind.AliasQualifiedName: var oldAliasQualifiedName = (AliasQualifiedNameSyntax)oldName; var newAliasQualifiedName = (AliasQualifiedNameSyntax)newName; return CompareNames(oldAliasQualifiedName.Alias, newAliasQualifiedName.Alias) && CompareNames(oldAliasQualifiedName.Name, newAliasQualifiedName.Name); } Debug.Fail("Unknown kind: " + oldName.Kind()); return false; }
public NamespaceDeclarationSyntax Update(SyntaxToken namespaceKeyword, NameSyntax name, SyntaxToken openBraceToken, SyntaxList <ExternAliasDirectiveSyntax> externs, SyntaxList <UsingDirectiveSyntax> usings, SyntaxList <MemberDeclarationSyntax> members, SyntaxToken closeBraceToken, SyntaxToken semicolonToken) => this.Update(this.AttributeLists, this.Modifiers, namespaceKeyword, name, openBraceToken, externs, usings, members, closeBraceToken, semicolonToken);