public override ExpressionSyntax VisitNamespace(INamespaceSymbol symbol) { var syntax = AddInformationTo(symbol.Name.ToIdentifierName(), symbol); if (symbol.ContainingNamespace == null) { return(syntax); } if (symbol.ContainingNamespace.IsGlobalNamespace) { return(AddInformationTo( SyntaxFactory.AliasQualifiedName( SyntaxFactory.IdentifierName( SyntaxFactory.Token(SyntaxKind.GlobalKeyword) ), syntax ), symbol )); } else { var container = symbol.ContainingNamespace.Accept(this) !; return(CreateMemberAccessExpression(symbol, container, syntax)); } }
/// <summary> /// We always unilaterally add "global::" to all named types/namespaces. This /// will then be trimmed off if possible by calls to /// <see cref="Simplifier.ReduceAsync(Document, OptionSet, CancellationToken)"/> /// </summary> private TypeSyntax AddGlobalAlias(INamespaceOrTypeSymbol symbol, SimpleNameSyntax syntax) { return(AddInformationTo( SyntaxFactory.AliasQualifiedName( CreateGlobalIdentifier(), syntax), symbol)); }
/// <summary> /// Returns <see cref="ParenthesizedExpressionSyntax"/> representing parenthesized binary expression of <paramref name="bindingFlags"/>. /// </summary> /// <param name="operationKind"> /// The kind of the binary expression. /// </param> /// <param name="bindingFlags"> /// The binding flags. /// </param> /// <returns> /// <see cref="ParenthesizedExpressionSyntax"/> representing parenthesized binary expression of <paramref name="bindingFlags"/>. /// </returns> public static ParenthesizedExpressionSyntax GetBindingFlagsParenthesizedExpressionSyntax(SyntaxKind operationKind, params BindingFlags[] bindingFlags) { if (bindingFlags.Length < 2) { throw new ArgumentOutOfRangeException( "bindingFlags", string.Format("Can't create parenthesized binary expression with {0} arguments", bindingFlags.Length)); } var flags = SyntaxFactory.AliasQualifiedName(SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), SyntaxFactory.IdentifierName("System")).Member("Reflection").Member("BindingFlags"); var bindingFlagsBinaryExpression = SyntaxFactory.BinaryExpression( operationKind, flags.Member(bindingFlags[0].ToString()), flags.Member(bindingFlags[1].ToString())); for (var i = 2; i < bindingFlags.Length; i++) { bindingFlagsBinaryExpression = SyntaxFactory.BinaryExpression( operationKind, bindingFlagsBinaryExpression, flags.Member(bindingFlags[i].ToString())); } return(SyntaxFactory.ParenthesizedExpression(bindingFlagsBinaryExpression)); }
private static QualifiedNameSyntax CreateSystemObject() { return(SyntaxFactory.QualifiedName( SyntaxFactory.AliasQualifiedName( CreateGlobalIdentifier(), SyntaxFactory.IdentifierName("System")), SyntaxFactory.IdentifierName("Object"))); }
public override ExpressionSyntax VisitNamedType(INamedTypeSymbol symbol) { if ( TypeSyntaxGeneratorVisitor.TryCreateNativeIntegerType( symbol, out var typeSyntax ) ) { return(typeSyntax); } typeSyntax = TypeSyntaxGeneratorVisitor.Create().CreateSimpleTypeSyntax(symbol); if (!(typeSyntax is SimpleNameSyntax)) { return(typeSyntax); } var simpleNameSyntax = (SimpleNameSyntax)typeSyntax; if (symbol.ContainingType != null) { if (symbol.ContainingType.TypeKind == TypeKind.Submission) { return(simpleNameSyntax); } else { var container = symbol.ContainingType.Accept(this) !; return(CreateMemberAccessExpression(symbol, container, simpleNameSyntax)); } } else if (symbol.ContainingNamespace != null) { if (symbol.ContainingNamespace.IsGlobalNamespace) { if (symbol.TypeKind != TypeKind.Error) { return(AddInformationTo( SyntaxFactory.AliasQualifiedName( SyntaxFactory.IdentifierName( SyntaxFactory.Token(SyntaxKind.GlobalKeyword) ), simpleNameSyntax ), symbol )); } } else { var container = symbol.ContainingNamespace.Accept(this) !; return(CreateMemberAccessExpression(symbol, container, simpleNameSyntax)); } } return(simpleNameSyntax); }
public override SyntaxNode MakeSyntaxNode() { var res = SyntaxFactory.AliasQualifiedName(Alias, ColonColonToken, Name); // if (Arity != null) res = res.WithArity(Arity); // if (IsVar != null) res = res.WithIsVar(IsVar); IsChanged = false; return(res); }
public override TypeSyntax VisitNamedType(INamedTypeSymbol symbol) { var typeSyntax = CreateSimpleTypeSyntax(symbol); if (!(typeSyntax is SimpleNameSyntax)) { return(typeSyntax); } var simpleNameSyntax = (SimpleNameSyntax)typeSyntax; if (symbol.ContainingType != null) { if (symbol.ContainingType.TypeKind == TypeKind.Submission) { return(typeSyntax); } else { var containingTypeSyntax = symbol.ContainingType.Accept(this); if (containingTypeSyntax is NameSyntax) { return(AddInformationTo( SyntaxFactory.QualifiedName((NameSyntax)containingTypeSyntax, simpleNameSyntax), symbol)); } else { return(AddInformationTo(simpleNameSyntax, symbol)); } } } else if (symbol.ContainingNamespace != null) { if (symbol.ContainingNamespace.IsGlobalNamespace) { if (symbol.TypeKind != TypeKind.Error) { return(AddInformationTo( SyntaxFactory.AliasQualifiedName( SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), simpleNameSyntax), symbol)); } } else { var container = symbol.ContainingNamespace.Accept(this); return(AddInformationTo(SyntaxFactory.QualifiedName( (NameSyntax)container, simpleNameSyntax), symbol)); } } return(simpleNameSyntax); }
internal static NameSyntax PrependExternAlias(IdentifierNameSyntax externAliasSyntax, NameSyntax nameSyntax) { if (nameSyntax is QualifiedNameSyntax qualifiedNameSyntax) { return(SyntaxFactory.QualifiedName( PrependExternAlias(externAliasSyntax, qualifiedNameSyntax.Left), qualifiedNameSyntax.Right)); } else { return(SyntaxFactory.AliasQualifiedName(externAliasSyntax, (SimpleNameSyntax)nameSyntax)); } }
public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node) { if (_ignore.Contains(node.ToString())) { return(node); } if (node.Parent != null) { return(node); } return(SyntaxFactory.AliasQualifiedName(SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), node)); }
/// <summary> /// Converts a <see cref="Type"/> to a <see cref="TypeSyntax"/>. /// </summary> /// <param name="t">The type</param> /// <param name="useGlobalAlias">Whether the to qualify type names with "global::"</param> /// <returns>A <see cref="TypeSyntax"/> representing the type.</returns> public static TypeSyntax ToTypeSyntax(this Type t, bool useGlobalAlias = false) { if (t == typeof(void)) { return(SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword))); } if (t.IsGenericParameter) { return(SyntaxFactory.IdentifierName(t.Name)); } if (t.IsArray) { return(SyntaxFactory.ArrayType( t.GetElementType().ToTypeSyntax(useGlobalAlias), SyntaxFactory.SingletonList( SyntaxFactory.ArrayRankSpecifier( SyntaxFactory.SingletonSeparatedList <ExpressionSyntax>( SyntaxFactory.OmittedArraySizeExpression()))))); } if (t.IsPointer) { return(SyntaxFactory.PointerType(t.GetElementType().ToTypeSyntax(useGlobalAlias))); } TypeSyntax qualification = t.IsNested ? t.DeclaringType.ToTypeSyntax(useGlobalAlias) : t.Namespace.Split('.') .Select(s => (NameSyntax)SyntaxFactory.IdentifierName(s)) .Aggregate((acc, next) => { // see if we should qualify with global:: NameSyntax left = useGlobalAlias && acc is IdentifierNameSyntax identifier ? SyntaxFactory.AliasQualifiedName(SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), identifier) : acc; return(SyntaxFactory.QualifiedName(left, (SimpleNameSyntax)next)); }); SimpleNameSyntax name = t.IsGenericType ? SyntaxFactory.GenericName(t.Name.Substring(0, t.Name.IndexOf('`', StringComparison.Ordinal))) .WithTypeArgumentList(SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(t.GenericTypeArguments.Select(typeArg => typeArg.ToTypeSyntax(useGlobalAlias))))) : (SimpleNameSyntax)SyntaxFactory.IdentifierName(t.Name); return(SyntaxFactory.QualifiedName((NameSyntax)qualification, name)); }
private NameSyntax AddOrReplaceAlias(NameSyntax nameSyntax, IdentifierNameSyntax alias) { if (nameSyntax is SimpleNameSyntax simpleName) { return(SyntaxFactory.AliasQualifiedName(alias, simpleName)); } if (nameSyntax is QualifiedNameSyntax qualifiedName) { return(qualifiedName.WithLeft(AddOrReplaceAlias(qualifiedName.Left, alias))); } var aliasName = nameSyntax as AliasQualifiedNameSyntax; return(aliasName.WithAlias(alias)); }
private static ExpressionSyntax GenerateMemberAccess(params string[] names) { ExpressionSyntax result = SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)); for (int i = 0; i < names.Length; i++) { var name = SyntaxFactory.IdentifierName(names[i]); if (i == 0) { result = SyntaxFactory.AliasQualifiedName((IdentifierNameSyntax)result, name); } else { result = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, result, name); } } return(result); }
private async Task <Solution> ReplaceParameter(Diagnostic diagnostic, CodeFixContext context, CancellationToken cancellationToken) { var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); var diagnosticSpan = diagnostic.Location.SourceSpan; // Find the type declaration identified by the diagnostic. var methodDeclaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType <MethodDeclarationSyntax>().First(); var parameterList = methodDeclaration.ParameterList; TypeSyntax parameterTypeSyntax; if (parameterList.Parameters.Count > 0) { var firstParameter = parameterList.Parameters.First(); var typeInfo = semanticModel.GetTypeInfo(firstParameter.Type); if (NDPGenerator.TypeSymbolMatchesType(typeInfo.ConvertedType, Generator.OnChangingArgs, semanticModel, false)) { parameterTypeSyntax = firstParameter.Type; // if we had the correct type then its ok. } else { var newType = firstParameter.Type; if (NDPGenerator.TypeSymbolMatchesType(typeInfo.ConvertedType, typeof(NDProperty.Propertys.OnChangingArg <, ,>), semanticModel, false) || NDPGenerator.TypeSymbolMatchesType(typeInfo.ConvertedType, typeof(NDProperty.Propertys.OnChangingArg <,>), semanticModel, false)) { newType = firstParameter.Type.DescendantNodesAndSelf().OfType <GenericNameSyntax>().First().TypeArgumentList.Arguments.First(); } parameterTypeSyntax = SyntaxFactory.QualifiedName( SyntaxFactory.QualifiedName( SyntaxFactory.AliasQualifiedName( SyntaxFactory.IdentifierName( SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), SyntaxFactory.IdentifierName(nameof(NDProperty))), SyntaxFactory.IdentifierName(nameof(NDProperty.Propertys))), GetTypeArgumentList(SyntaxFactory.GenericName( SyntaxFactory.Identifier(nameof(NDProperty.Propertys.OnChangingArg))), newType)); } } else { parameterTypeSyntax = SyntaxFactory.QualifiedName( SyntaxFactory.QualifiedName( SyntaxFactory.AliasQualifiedName( SyntaxFactory.IdentifierName( SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), SyntaxFactory.IdentifierName(nameof(NDProperty))), SyntaxFactory.IdentifierName(nameof(NDProperty.Propertys))), GetTypeArgumentList(SyntaxFactory.GenericName( SyntaxFactory.Identifier(nameof(NDProperty.Propertys.OnChangingArg))), SyntaxFactory.PredefinedType( SyntaxFactory.Token(SyntaxKind.ObjectKeyword)))); } var newParameterList = SyntaxFactory.ParameterList( SyntaxFactory.SingletonSeparatedList( SyntaxFactory.Parameter( SyntaxFactory.Identifier("arg")) .WithType(parameterTypeSyntax))); root = root.ReplaceNode(parameterList, newParameterList); // Produce a new solution that has all references to that type renamed, including the declaration. var originalSolution = context.Document.Project.Solution; return(originalSolution.WithDocumentSyntaxRoot(context.Document.Id, root)); }
/// <summary> /// Try to get a new node to replace given node, which is a reference to a top-level type declared inside the namespce to be changed. /// If this reference is the right side of a qualified name, the new node returned would be the entire qualified name. Depends on /// whether <paramref name="newNamespaceParts"/> is provided, the name in the new node might be qualified with this new namespace instead. /// </summary> /// <param name="reference">A reference to a type declared inside the namespce to be changed, which is calculated based on results from /// `SymbolFinder.FindReferencesAsync`.</param> /// <param name="newNamespaceParts">If specified, and the reference is qualified with namespace, the namespace part of original reference /// will be replaced with given namespace in the new node.</param> /// <param name="old">The node to be replaced. This might be an ancestor of original reference.</param> /// <param name="new">The replacement node.</param> public override bool TryGetReplacementReferenceSyntax( SyntaxNode reference, ImmutableArray <string> newNamespaceParts, ISyntaxFactsService syntaxFacts, out SyntaxNode old, out SyntaxNode @new) { if (!(reference is SimpleNameSyntax nameRef)) { old = @new = null; return(false); } // A few different cases are handled here: // // 1. When the reference is not qualified (i.e. just a simple name), then there's nothing need to be done. // And both old and new will point to the original reference. // // 2. When the new namespace is not specified, we don't need to change the qualified part of reference. // Both old and new will point to the qualified reference. // // 3. When the new namespace is "", i.e. we are moving type referenced by name here to global namespace. // As a result, we need replace qualified reference with the simple name. // // 4. When the namespace is specified and not "", i.e. we are moving referenced type to a different non-global // namespace. We need to replace the qualified reference with a new qualified reference (which is qualified // with new namespace.) if (syntaxFacts.IsRightSideOfQualifiedName(nameRef)) { old = nameRef.Parent; var aliasQualifier = GetAliasQualifierOpt(old); if (IsGlobalNamespace(newNamespaceParts)) { // If new namespace is "", then name will be declared in global namespace. // We will replace qualified reference with simple name qualified with alias (global if it's not alias qualified) var aliasNode = aliasQualifier?.ToIdentifierName() ?? SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)); @new = SyntaxFactory.AliasQualifiedName(aliasNode, nameRef.WithoutTrivia()); } else { var qualifiedNamespaceName = CreateNameSyntax(newNamespaceParts, aliasQualifier, newNamespaceParts.Length - 1); @new = SyntaxFactory.QualifiedName(qualifiedNamespaceName, nameRef.WithoutTrivia()); } // We might lose some trivia associated with children of `outerMostNode`. @new = @new.WithTriviaFrom(old); return(true); } if (nameRef.Parent is NameMemberCrefSyntax crefName && crefName.Parent is QualifiedCrefSyntax qualifiedCref) { // This is the case where the reference is the right most part of a qualified name in `cref`. // for example, `<see cref="Foo.Baz.Bar"/>` and `<see cref="SomeAlias::Foo.Baz.Bar"/>`. // This is the form of `cref` we need to handle as a spacial case when changing namespace name or // changing namespace from non-global to global, other cases in these 2 scenarios can be handled in the // same way we handle non cref references, for example, `<see cref="SomeAlias::Foo"/>` and `<see cref="Foo"/>`. var container = qualifiedCref.Container; var aliasQualifier = GetAliasQualifierOpt(container); if (IsGlobalNamespace(newNamespaceParts)) { // If new namespace is "", then name will be declared in global namespace. // We will replace entire `QualifiedCrefSyntax` with a `TypeCrefSyntax`, // which is a alias qualified simple name, similar to the regular case above. old = qualifiedCref; var aliasNode = aliasQualifier?.ToIdentifierName() ?? SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)); var aliasQualifiedNode = SyntaxFactory.AliasQualifiedName(aliasNode, nameRef.WithoutTrivia()); @new = SyntaxFactory.TypeCref(aliasQualifiedNode); } else { // if the new namespace is not global, then we just need to change the container in `QualifiedCrefSyntax`, // which is just a regular namespace node, no cref node involve here. old = container; @new = CreateNameSyntax(newNamespaceParts, aliasQualifier, newNamespaceParts.Length - 1); } return(true); } // Simple name reference, nothing to be done. // The name will be resolved by adding proper import. old = @new = nameRef; return(false); }
/// <summary> /// Returns syntax for the deserializer method. /// </summary> /// <param name="type">The type.</param> /// <param name="fields">The fields.</param> /// <returns>Syntax for the deserializer method.</returns> private static MemberDeclarationSyntax GenerateDeserializerMethod(Type type, List <FieldInfoMember> fields) { Expression <Action> deserializeInner = () => SerializationManager.DeserializeInner(default(Type), default(BinaryTokenStreamReader)); var streamParameter = SF.IdentifierName("stream"); var resultDeclaration = SF.LocalDeclarationStatement( SF.VariableDeclaration(type.GetTypeSyntax()) .AddVariables( SF.VariableDeclarator("result") .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type))))); var resultVariable = SF.IdentifierName("result"); var body = new List <StatementSyntax> { resultDeclaration }; // Value types cannot be referenced, only copied, so there is no need to box & record instances of value types. if (!type.IsValueType) { // Record the result for cyclic deserialization. Expression <Action> recordObject = () => DeserializationContext.Current.RecordObject(default(object)); var currentSerializationContext = SyntaxFactory.AliasQualifiedName( SF.IdentifierName(SF.Token(SyntaxKind.GlobalKeyword)), SF.IdentifierName("Orleans")) .Qualify("Serialization") .Qualify("DeserializationContext") .Qualify("Current"); body.Add( SF.ExpressionStatement( recordObject.Invoke(currentSerializationContext) .AddArgumentListArguments(SF.Argument(resultVariable)))); } // Deserialize all fields. foreach (var field in fields) { var deserialized = deserializeInner.Invoke() .AddArgumentListArguments( SF.Argument(SF.TypeOfExpression(field.Type)), SF.Argument(streamParameter)); body.Add( SF.ExpressionStatement( field.GetSetter( resultVariable, SF.CastExpression(field.Type, deserialized)))); } body.Add(SF.ReturnStatement(SF.CastExpression(type.GetTypeSyntax(), resultVariable))); return (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "Deserializer") .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword)) .AddParameterListParameters( SF.Parameter(SF.Identifier("expected")).WithType(typeof(Type).GetTypeSyntax()), SF.Parameter(SF.Identifier("stream")).WithType(typeof(BinaryTokenStreamReader).GetTypeSyntax())) .AddBodyStatements(body.ToArray()) .AddAttributeLists( SF.AttributeList() .AddAttributes(SF.Attribute(typeof(DeserializerMethodAttribute).GetNameSyntax())))); }
/// <summary> /// Returns syntax for the deep copier method. /// </summary> /// <param name="type">The type.</param> /// <param name="fields">The fields.</param> /// <returns>Syntax for the deep copier method.</returns> private static MemberDeclarationSyntax GenerateDeepCopierMethod(Type type, List <FieldInfoMember> fields) { var originalVariable = SF.IdentifierName("original"); var inputVariable = SF.IdentifierName("input"); var resultVariable = SF.IdentifierName("result"); var body = new List <StatementSyntax>(); if (type.GetCustomAttribute <ImmutableAttribute>() != null) { // Immutable types do not require copying. body.Add(SF.ReturnStatement(originalVariable)); } else { body.Add( SF.LocalDeclarationStatement( SF.VariableDeclaration(type.GetTypeSyntax()) .AddVariables( SF.VariableDeclarator("input") .WithInitializer( SF.EqualsValueClause( SF.ParenthesizedExpression( SF.CastExpression(type.GetTypeSyntax(), originalVariable))))))); body.Add( SF.LocalDeclarationStatement( SF.VariableDeclaration(type.GetTypeSyntax()) .AddVariables( SF.VariableDeclarator("result") .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type)))))); // Copy all members from the input to the result. foreach (var field in fields) { body.Add(SF.ExpressionStatement(field.GetSetter(resultVariable, field.GetGetter(inputVariable)))); } // Record this serialization. Expression <Action> recordObject = () => SerializationContext.Current.RecordObject(default(object), default(object)); var currentSerializationContext = SyntaxFactory.AliasQualifiedName( SF.IdentifierName(SF.Token(SyntaxKind.GlobalKeyword)), SF.IdentifierName("Orleans")) .Qualify("Serialization") .Qualify("SerializationContext") .Qualify("Current"); body.Add( SF.ExpressionStatement( recordObject.Invoke(currentSerializationContext) .AddArgumentListArguments(SF.Argument(originalVariable), SF.Argument(resultVariable)))); body.Add(SF.ReturnStatement(resultVariable)); } return (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "DeepCopier") .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword)) .AddParameterListParameters( SF.Parameter(SF.Identifier("original")).WithType(typeof(object).GetTypeSyntax())) .AddBodyStatements(body.ToArray()) .AddAttributeLists( SF.AttributeList().AddAttributes(SF.Attribute(typeof(CopierMethodAttribute).GetNameSyntax())))); }
private ExpressionSyntax FullyQualifyIdentifierName( ISymbol symbol, ExpressionSyntax rewrittenNode, ExpressionSyntax originalNode, bool replaceNode, bool isInsideCref, bool omitLeftHandSide) { Debug.Assert(!replaceNode || rewrittenNode.Kind() == SyntaxKind.IdentifierName); //// TODO: use and expand Generate*Syntax(isymbol) to not depend on symbol display any more. //// See GenerateExpressionSyntax(); var result = rewrittenNode; // only if this symbol has a containing type or namespace there is work for us to do. if (replaceNode || symbol.ContainingType != null || symbol.ContainingNamespace != null) { ImmutableArray <SymbolDisplayPart> displayParts; ExpressionSyntax left = null; // we either need to create an AliasQualifiedName if the symbol is directly contained in the global namespace, // otherwise it a QualifiedName. if (!replaceNode && symbol.ContainingType == null && symbol.ContainingNamespace.IsGlobalNamespace) { return(rewrittenNode.CopyAnnotationsTo( SyntaxFactory.AliasQualifiedName( SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), (SimpleNameSyntax)rewrittenNode.WithLeadingTrivia(null)) .WithLeadingTrivia(rewrittenNode.GetLeadingTrivia()))); } displayParts = replaceNode ? symbol.ToDisplayParts(s_typeNameFormatWithGenerics) : ((ISymbol)symbol.ContainingType ?? (ISymbol)symbol.ContainingNamespace).ToDisplayParts(s_typeNameFormatWithGenerics); rewrittenNode = TryAddTypeArgumentToIdentifierName(rewrittenNode, symbol); // Replaces the '<' token with the '{' token since we are inside crefs rewrittenNode = TryReplaceAngleBracesWithCurlyBraces(rewrittenNode, isInsideCref); result = rewrittenNode; if (!omitLeftHandSide) { left = SyntaxFactory.ParseTypeName(displayParts.ToDisplayString()); // Replaces the '<' token with the '{' token since we are inside crefs left = TryReplaceAngleBracesWithCurlyBraces(left, isInsideCref); if (replaceNode) { return(left .WithLeadingTrivia(rewrittenNode.GetLeadingTrivia()) .WithTrailingTrivia(rewrittenNode.GetTrailingTrivia())); } // now create syntax for the combination of left and right syntax, or a simple replacement in case of an identifier var parent = originalNode.Parent; var leadingTrivia = rewrittenNode.GetLeadingTrivia(); rewrittenNode = rewrittenNode.WithLeadingTrivia(null); switch (parent.Kind()) { case SyntaxKind.QualifiedName: var qualifiedParent = (QualifiedNameSyntax)parent; result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.QualifiedName( (NameSyntax)left, (SimpleNameSyntax)rewrittenNode)); break; case SyntaxKind.SimpleMemberAccessExpression: var memberAccessParent = (MemberAccessExpressionSyntax)parent; result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, left, (SimpleNameSyntax)rewrittenNode)); break; default: Debug.Assert(rewrittenNode is SimpleNameSyntax); if (SyntaxFacts.IsInNamespaceOrTypeContext(originalNode)) { var right = (SimpleNameSyntax)rewrittenNode; result = rewrittenNode.CopyAnnotationsTo(SyntaxFactory.QualifiedName((NameSyntax)left, right.WithAdditionalAnnotations(Simplifier.SpecialTypeAnnotation))); } else if (originalNode.Parent is CrefSyntax) { var right = (SimpleNameSyntax)rewrittenNode; result = rewrittenNode.CopyAnnotationsTo(SyntaxFactory.QualifiedName((NameSyntax)left, right)); } else { result = rewrittenNode.CopyAnnotationsTo( SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, left, (SimpleNameSyntax)rewrittenNode)); } break; } result = result.WithLeadingTrivia(leadingTrivia); } } return(result); }