public void Namespaces_MultipleTypesWithDifferentNamespaces() { //-- arrange var generatorUnderTest = new CSharpSyntaxGenerator(); var typesToCompile = new TypeMember[] { new TypeMember("My.Namespace1", MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"), new TypeMember("My.Namespace2", MemberVisibility.Public, TypeMemberKind.Class, "ClassTwo"), new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassA"), new TypeMember("My.Namespace1", MemberVisibility.Public, TypeMemberKind.Class, "ClassThree"), new TypeMember("My.Namespace2", MemberVisibility.Public, TypeMemberKind.Class, "ClassFour"), new TypeMember(MemberVisibility.Public, TypeMemberKind.Class, "ClassB"), }; //-- act SyntaxTree syntax = generatorUnderTest.GenerateSyntax(typesToCompile); //-- assert syntax.Should().BeEquivalentToCode(@" public class ClassA { } public class ClassB { } namespace My.Namespace1 { public class ClassOne { } public class ClassThree { } } namespace My.Namespace2 { public class ClassTwo { } public class ClassFour { } } "); }
public override TDeclarationNode AddParameters <TDeclarationNode>( TDeclarationNode destination, IEnumerable <IParameterSymbol> parameters, CodeGenerationOptions options, CancellationToken cancellationToken) { var currentParameterList = CSharpSyntaxGenerator.GetParameterList(destination); if (currentParameterList == null) { return(destination); } var currentParamsCount = currentParameterList.Parameters.Count; var seenOptional = currentParamsCount > 0 && currentParameterList.Parameters[currentParamsCount - 1].Default != null; var isFirstParam = currentParamsCount == 0; var newParams = ArrayBuilder <SyntaxNode> .GetInstance(); foreach (var parameter in parameters) { var parameterSyntax = ParameterGenerator.GetParameter(parameter, options, isExplicit: false, isFirstParam: isFirstParam, seenOptional: seenOptional); isFirstParam = false; seenOptional = seenOptional || parameterSyntax.Default != null; newParams.Add(parameterSyntax); } var finalMember = CSharpSyntaxGenerator.Instance.AddParameters(destination, newParams.ToImmutableAndFree()); return(Cast <TDeclarationNode>(finalMember)); }
public void Usings_SomeTypeNamesDuplicate_OnlyDuplicatesReferredByQualifiedName() { //-- arrange var generatorUnderTest = new CSharpSyntaxGenerator(); var typeFirstClassA = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "ClassA"); var typeFirstClassB = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "ClassB"); var typeSecondClassA = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassA"); var typeSecondClassC = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassC"); var typeThirdClassD = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Third", MemberVisibility.Public, TypeMemberKind.Class, "ClassD"); typeThirdClassD.Members.Add(new PropertyMember(typeThirdClassD, MemberVisibility.Public, MemberModifier.None, typeFirstClassA, "FirstA")); typeThirdClassD.Members.Add(new PropertyMember(typeThirdClassD, MemberVisibility.Public, MemberModifier.None, typeFirstClassB, "FirstB")); typeThirdClassD.Members.Add(new PropertyMember(typeThirdClassD, MemberVisibility.Public, MemberModifier.None, typeSecondClassA, "SecondA")); typeThirdClassD.Members.Add(new PropertyMember(typeThirdClassD, MemberVisibility.Public, MemberModifier.None, typeSecondClassC, "SecondC")); //-- act SyntaxTree syntax = generatorUnderTest.GenerateSyntax( typesToCompile: new[] { typeFirstClassA, typeFirstClassB, typeSecondClassA, typeSecondClassC, typeThirdClassD }, allReferencedTypes: new[] { typeFirstClassA, typeFirstClassB, typeSecondClassA, typeSecondClassC }); //-- assert syntax.Should().BeEquivalentToCode(@" using My.First; using My.Second; namespace My.First { public class ClassA { } public class ClassB { } } namespace My.Second { public class ClassA { } public class ClassC { } } namespace My.Third { public class ClassD { public My.First.ClassA FirstA { get; } public ClassB FirstB { get; } public My.Second.ClassA SecondA { get; } public ClassC SecondC { get; } } } "); }
protected override SyntaxNode CreateExplicitlyCastedLiteralValue( INamedTypeSymbol enumType, SpecialType underlyingSpecialType, object constantValue) { var expression = ExpressionGenerator.GenerateNonEnumValueExpression( enumType.EnumUnderlyingType, constantValue, canUseFieldReference: true); var constantValueULong = EnumUtilities.ConvertEnumUnderlyingTypeToUInt64(constantValue, underlyingSpecialType); if (constantValueULong == 0) { // 0 is always convertible to an enum type without needing a cast. return expression; } var factory = new CSharpSyntaxGenerator(); return factory.CastExpression(enumType, expression); }
private static SyntaxTokenList GenerateModifiers( IParameterSymbol parameter, bool isFirstParam) { SyntaxTokenList list = CSharpSyntaxGenerator.GetParameterModifiers(parameter.RefKind); if (isFirstParam && parameter.ContainingSymbol is IMethodSymbol methodSymbol && methodSymbol.IsExtensionMethod) { list = list.Add(SyntaxFactory.Token(SyntaxKind.ThisKeyword)); } if (parameter.IsParams) { list = list.Add(SyntaxFactory.Token(SyntaxKind.ParamsKeyword)); } return(list); }
protected override SyntaxNode CreateExplicitlyCastedLiteralValue( INamedTypeSymbol enumType, SpecialType underlyingSpecialType, object constantValue) { var expression = ExpressionGenerator.GenerateNonEnumValueExpression( enumType.EnumUnderlyingType, constantValue, canUseFieldReference: true); var constantValueULong = EnumUtilities.ConvertEnumUnderlyingTypeToUInt64(constantValue, underlyingSpecialType); if (constantValueULong == 0) { // 0 is always convertible to an enum type without needing a cast. return(expression); } var factory = new CSharpSyntaxGenerator(); return(factory.CastExpression(enumType, expression)); }
public void Namespaces_SingleTypeWithNamespace() { //-- arrange var generatorUnderTest = new CSharpSyntaxGenerator(); var typesToCompile = new TypeMember[] { new TypeMember("My.Namespace", MemberVisibility.Public, TypeMemberKind.Class, "MyClass") }; //-- act SyntaxTree syntax = generatorUnderTest.GenerateSyntax(typesToCompile); //-- assert syntax.Should().BeEquivalentToCode(@" namespace My.Namespace { public class MyClass { } } "); }
public void Usings_UniqueTypeNames_ReferredByShortName() { //-- arrange var generatorUnderTest = new CSharpSyntaxGenerator(); var type1 = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "ClassOne"); var type2 = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassTwo"); type1.Members.Add(new PropertyMember(type1, MemberVisibility.Public, MemberModifier.None, typeof(DateTime), "Time")); type2.BaseType = type1; //-- act SyntaxTree syntax = generatorUnderTest.GenerateSyntax( typesToCompile: new[] { type1, type2 }, allReferencedTypes: new[] { type1, (TypeMember)typeof(DateTime) }); //-- assert syntax.Should().BeEquivalentToCode(@" using System; using My.First; namespace My.First { public class ClassOne { public DateTime Time { get; } } } namespace My.Second { public class ClassTwo : ClassOne { } } "); }
protected override BaseParameterListSyntax TryGetApplicableList(SyntaxNode node) => CSharpSyntaxGenerator.GetParameterList(node);
protected void AddSyntax(TextWriter writer) { var csharpSyntax = new CSharpSyntaxGenerator(this._version).GenerateSyntax(this._versionType); base.AddSyntax(writer, csharpSyntax); }
public override TypeSyntax VisitFunctionPointerType(IFunctionPointerTypeSymbol symbol) { // TODO(https://github.com/dotnet/roslyn/issues/39865): generate the calling convention once exposed through the API var parameters = symbol.Signature.Parameters.Select(p => (p.Type, RefKindModifiers: CSharpSyntaxGenerator.GetParameterModifiers(p.RefKind))) .Concat(SpecializedCollections.SingletonEnumerable(( Type: symbol.Signature.ReturnType, RefKindModifiers: CSharpSyntaxGenerator.GetParameterModifiers(symbol.Signature.RefKind, forFunctionPointerReturnParameter: true)))) .SelectAsArray(t => SyntaxFactory.Parameter(SyntaxFactory.MissingToken(SyntaxKind.IdentifierToken)).WithModifiers(t.RefKindModifiers).WithType(t.Type.GenerateTypeSyntax())); return(AddInformationTo( SyntaxFactory.FunctionPointerType(SyntaxFactory.SeparatedList(parameters)), symbol)); }
public void Usings_DuplicateTypeNamesWithDifferentGenericArity_ReferredByShortName() { //-- arrange var generatorUnderTest = new CSharpSyntaxGenerator(); var typeClassList = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "List"); var typeClassListInOut = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "List", new TypeMember(MemberVisibility.Public, TypeMemberKind.GenericParameter, "TInner"), new TypeMember(MemberVisibility.Public, TypeMemberKind.GenericParameter, "TOuter")) { IsGenericType = true, IsGenericTypeDefinition = true }; var typeSecondClassA = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassA") { BaseType = typeClassList }; var typeListOfInt = ((TypeMember)typeof(List <>)).MakeGenericType(typeof(int)); typeSecondClassA.Members.Add(new PropertyMember( typeSecondClassA, MemberVisibility.Public, MemberModifier.None, typeListOfInt, "Numbers")); //-- act SyntaxTree syntax = generatorUnderTest.GenerateSyntax( typesToCompile: new[] { typeClassList, typeClassListInOut, typeSecondClassA }, allReferencedTypes: new[] { typeClassList, typeClassListInOut, typeSecondClassA, typeof(List <>) }); //-- assert syntax.Should().BeEquivalentToCode(@" using System.Collections.Generic; using My.First; using My.Second; namespace My.First { public class List { } public class List<TInner,TOuter> { } } namespace My.Second { public class ClassA : List { public List<int> Numbers { get; } } } "); }
public void Usings_GenericTypeNames_RulesApplyRecursively() { //-- arrange var generatorUnderTest = new CSharpSyntaxGenerator(); var typeFirstClassA = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "ClassA"); var typeFirstClassList = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.First", MemberVisibility.Public, TypeMemberKind.Class, "List", new TypeMember(new TypeGeneratorInfo(this.GetType()), null, MemberVisibility.Public, TypeMemberKind.GenericParameter, "T")); var typeSecondClassA = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassA"); var typeSecondClassB = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Second", MemberVisibility.Public, TypeMemberKind.Class, "ClassB"); var typeThirdClassC = new TypeMember(new TypeGeneratorInfo(this.GetType()), "My.Third", MemberVisibility.Public, TypeMemberKind.Class, "ClassC"); TypeMember typeGenericDictionary = typeof(Dictionary <,>); TypeMember typeGenericList = typeof(List <>); var typeDictionaryOfFirstClassASecondClassA = typeGenericDictionary.MakeGenericType(typeFirstClassA, typeSecondClassA); var typeListOfSecondClassB = typeGenericList.MakeGenericType(typeSecondClassB); typeThirdClassC.Members.Add(new PropertyMember( typeThirdClassC, MemberVisibility.Public, MemberModifier.None, typeDictionaryOfFirstClassASecondClassA, "SecondByFirst")); typeThirdClassC.Members.Add(new PropertyMember( typeThirdClassC, MemberVisibility.Public, MemberModifier.None, typeListOfSecondClassB, "ListOfB")); //-- act SyntaxTree syntax = generatorUnderTest.GenerateSyntax( typesToCompile: new[] { typeFirstClassA, typeFirstClassList, typeSecondClassA, typeSecondClassB, typeThirdClassC }, allReferencedTypes: new[] { typeFirstClassA, typeFirstClassList, typeSecondClassA, typeSecondClassB, typeDictionaryOfFirstClassASecondClassA, typeListOfSecondClassB }); //-- assert syntax.Should().BeEquivalentToCode(@" using System.Collections.Generic; using My.Second; namespace My.First { public class ClassA { } public class List<T> { } } namespace My.Second { public class ClassA { } public class ClassB { } } namespace My.Third { public class ClassC { public Dictionary<My.First.ClassA, My.Second.ClassA> SecondByFirst { get; } public System.Collections.Generic.List<ClassB> ListOfB { get; } } } "); }