public static string Defaultvalue(this ITypeSymbol symbol) { if (symbol.IsReferenceType) { return("null"); } if (symbol.IsEnum()) { var v = symbol.GetMembers().OfType <IFieldSymbol>().FirstOrDefault(); if (v == null || Convert.ToInt32(v.ConstantValue) != 0) { return("0"); } return(v.Name); } if (symbol.SpecialType == SpecialType.None) { return($"default({symbol.Name})"); } var clrType = Type.GetType(symbol.FullName()); return(Activator.CreateInstance(clrType).ToString()); }
private static string GetPostconditionText(IEnumerable <Contract> contracts, ITypeSymbol type, string returnedExpression, string tempVarName) { var sb = new StringBuilder(); sb.AppendLine("{"); sb.AppendLine($" {type.FullName()} {tempVarName} = {returnedExpression};"); foreach (var c in contracts) { sb.AppendLine($" if (!({c.GetCondition(tempVarName, type)}))"); sb.AppendLine($" throw new global::Traction.PostconditionException(\"{c.ExceptionMessage}\");"); } sb.AppendLine($" return {tempVarName};"); sb.AppendLine("}"); return(sb.ToString()); }
protected override string GetTypeFullName(ITypeSymbol type) { CheckType(type); if (GetNativeTypeName(type, NativeTarget.C, out string name)) { return(name); } else if (type.SpecialType == SpecialType.System_Void) { return("void"); } else if (IsPrimitiveType(type)) { return(GetPrimitiveName(type)); } else if (type.Kind == SymbolKind.ArrayType) { var arrayType = (IArrayTypeSymbol)type; return(GetTypeFullName(arrayType.ElementType)); } else if (type.Kind == SymbolKind.PointerType) { var arrayType = (IPointerTypeSymbol)type; return(GetTypeFullName(arrayType.PointedAtType)); } else if (type.Kind == SymbolKind.NamedType && ((INamedTypeSymbol)type).IsGenericType) { string result = type.FullName(); int nestingCount = NestedCount(type); ParseImplementationDetail(ref result); return($"t{nestingCount}_{result}GENERIC"); } else { if (allowTypePrefix.enabled) { int nestingCount = NestedCount(type); return($"t{nestingCount}_" + base.GetTypeFullName(type)); } else { return(base.GetTypeFullName(type)); } } }
protected IAssemblySymbol ResolveContainingAssembly(ITypeSymbol type) { if (type.ContainingAssembly != null) { return(type.ContainingAssembly); } switch (type.Kind) { case SymbolKind.ArrayType: var arrayType = (IArrayTypeSymbol)type; return(ResolveContainingAssembly(arrayType.ElementType)); case SymbolKind.PointerType: var pointerType = (IPointerTypeSymbol)type; return(ResolveContainingAssembly(pointerType.PointedAtType)); } throw new Exception("Failed to resolve containing assembly: " + type.FullName()); }
private string GetRuntimeTypeFullName(ITypeSymbol type) { CheckType(type); string fullname = type.FullName(); if (type.Kind == SymbolKind.ArrayType) { fullname += "_ARRAY"; } else if (type.Kind == SymbolKind.PointerType) { fullname += "_PTR"; } else if (type.Kind == SymbolKind.NamedType && ((INamedTypeSymbol)type).IsGenericType) { fullname += "GENERIC"; } ParseImplementationDetail(ref fullname); int nestingCount = NestedCount(type); return($"rt{nestingCount}_" + fullname); }
protected ITypeSymbol ResolveType(ITypeSymbol type, IMethodSymbol usedWithinMethod) { if (type.Kind == SymbolKind.NamedType) { var symbol = (INamedTypeSymbol)type; // check if we need to resolve generic if (!symbol.IsGenericType) { return(symbol); } // if nested generic, resolve containing type and find resolved symbol if (symbol.TypeArguments.Length == 0) { if (symbol.ContainingType == null) { throw new NotSupportedException("Unsupported generic type: " + type.FullName()); } var containingType = (INamedTypeSymbol)ResolveType(symbol.ContainingType, usedWithinMethod); symbol = (INamedTypeSymbol)containingType.GetMembers().First(x => x.OriginalDefinition.IsEqual(symbol.OriginalDefinition)); } // check if all generic type args are resolved if (!symbol.TypeArguments.Any(x => x.TypeKind == TypeKind.TypeParameter)) { return(symbol); } // resolve generic parameters var parameters = symbol.TypeArguments; var typeParams = new ITypeSymbol[parameters.Length]; for (int i = 0; i != typeParams.Length; ++i) { typeParams[i] = ResolveType(parameters[i], usedWithinMethod); } // construct from generic source return(symbol.OriginalDefinition.Construct(typeParams)); } else if (type.Kind == SymbolKind.ArrayType) { var symbol = (IArrayTypeSymbol)type; var resolvedType = ResolveType(symbol.ElementType, usedWithinMethod); var compilation = GetCompilation(resolvedType); return(compilation.CreateArrayTypeSymbol(resolvedType)); } else if (type.Kind == SymbolKind.PointerType) { var symbol = (IPointerTypeSymbol)type; var resolvedType = ResolveType(symbol.PointedAtType, usedWithinMethod); var compilation = GetCompilation(resolvedType); return(compilation.CreatePointerTypeSymbol(resolvedType)); } else if (type.Kind == SymbolKind.TypeParameter) { var symbol = (ITypeParameterSymbol)type; if (symbol.TypeParameterKind == TypeParameterKind.Type) { var containingType = usedWithinMethod.ContainingType; while (containingType != null) { if (containingType.OriginalDefinition.IsEqual(symbol.ContainingType.OriginalDefinition)) { break; } containingType = containingType.ContainingType; } if (containingType == null) { throw new Exception("Failed to find ITypeParameterSymbol type: " + symbol.Name); } return(containingType.TypeArguments[symbol.Ordinal]); } else if (symbol.TypeParameterKind == TypeParameterKind.Method) { return(usedWithinMethod.TypeArguments[symbol.Ordinal]); } else { throw new NotSupportedException("Unsupported ITypeParameterSymbol kind: " + symbol.TypeParameterKind); } } return(type); }
public static bool IsNullable(this ITypeSymbol @this) => @this.FullName().EndsWith("?");
public void OnVisitSyntaxNode(GeneratorSyntaxContext context) { if (context.Node is ClassDeclarationSyntax cls) { ISymbol currentType = ModelExtensions.GetDeclaredSymbol(context.SemanticModel, cls); if (HasNamedAttribute( currentType, "Microsoft.DotNet.Internal.Testing.DependencyInjection.Abstractions.TestDependencyInjectionSetupAttribute" )) { bool error = false; var nested = cls.Parent as ClassDeclarationSyntax; if (nested == null) { Diagnostics.Add(Error(DiagnosticIds.NestedClassRequired, $"Class {cls.Identifier.Text} must be nested inside class to use [TestDependencyInjectionSetupAttribute]", cls)); error = true; } if (cls.Modifiers.All(m => m.Kind() != SyntaxKind.StaticKeyword)) { Diagnostics.Add(Error(DiagnosticIds.StaticClassRequired, $"Class {cls.Identifier.Text} must be declared static to use [TestDependencyInjectionSetupAttribute]", nested)); error = true; } if (!HasDependencyInjectionReference(context)) { Diagnostics.Add( Error( DiagnosticIds.DependencyInjectionRequired, "Missing reference to Microsoft.Extensions.DependencyInjection to use [TestDependencyInjectionSetupAttribute]", cls ) ); error = true; } if (error) { return; } if (nested.Modifiers.All(m => m.Kind() != SyntaxKind.PartialKeyword)) { Diagnostics.Add(Error(DiagnosticIds.PartialClassRequired, $"Class {nested.Identifier.Text} must be declared partial to use [TestDependencyInjectionSetupAttribute]", nested)); error = true; } if (!(nested.Parent is NamespaceDeclarationSyntax)) { Diagnostics.Add(Error(DiagnosticIds.NamespaceRequired, $"Class {nested.Identifier.Text} must be inside a namespace to use [TestDependencyInjectionSetupAttribute]", nested)); error = true; } if (error) { return; } ISymbol parentType = ModelExtensions.GetDeclaredSymbol(context.SemanticModel, nested); Declarations.Add( new TestConfigDeclaration( parentType.ContainingNamespace.FullName(), nested.Identifier.Text, currentType, cls ) ); } } if (context.Node is MethodDeclarationSyntax method) { var sMethod = ModelExtensions.GetDeclaredSymbol(context.SemanticModel, method) as IMethodSymbol; TestConfigDeclaration decl = Declarations.FirstOrDefault( d => d.DeclaringClassSymbol.Equals(sMethod.ContainingType, SymbolEqualityComparer.Default) ); if (decl == null) { return; } if (sMethod.Parameters.Length == 0) { return; } if (sMethod.Parameters[0].Type.FullName() != "Microsoft.Extensions.DependencyInjection.IServiceCollection") { return; } string configType; bool isConfigurationAsync; bool hasFetch; bool isFetchAsync; if (sMethod.ReturnsVoid) { configType = null; isConfigurationAsync = false; isFetchAsync = false; hasFetch = false; } else if (!(sMethod.ReturnType is INamedTypeSymbol returnType)) { return; } else if (returnType.FullName() == "System.Threading.Tasks.Task") { configType = null; isConfigurationAsync = true; isFetchAsync = false; hasFetch = false; } else if (returnType.IsGenericType) { if (returnType.ConstructedFrom.FullName() == "System.Action<T>" && returnType.TypeArguments[0].FullName() == "System.IServiceProvider") { configType = null; hasFetch = true; isFetchAsync = false; isConfigurationAsync = false; } else if (returnType.ConstructedFrom.FullName() == "System.Func<T,TResult>") { isConfigurationAsync = false; hasFetch = true; if (returnType.TypeArguments[0].FullName() != "System.IServiceProvider") { return; } ITypeSymbol funcReturn = returnType.TypeArguments[1]; if (funcReturn.FullName() == "System.Threading.Tasks.Task") { configType = null; isFetchAsync = true; } else if (funcReturn is INamedTypeSymbol { IsGenericType : true } namedFuncReturn&& namedFuncReturn.ConstructedFrom.FullName() == "System.Threading.Tasks.Task<TResult>") { configType = namedFuncReturn.TypeArguments[0].FullName(); isFetchAsync = true; } else { configType = funcReturn.FullName(); isFetchAsync = false; } } else if (returnType.ConstructedFrom.FullName() == "System.Threading.Tasks.Task<TResult>") { isConfigurationAsync = true; if (returnType.TypeArguments[0] is INamedTypeSymbol { IsGenericType : true } asyncReturn) { if (asyncReturn.ConstructedFrom.FullName() == "System.Action<T>" && asyncReturn.TypeArguments[0].FullName() == "System.IServiceProvider") { configType = null; hasFetch = true; isFetchAsync = false; } else if (asyncReturn.ConstructedFrom.FullName() == "System.Func<T,TResult>" && asyncReturn.TypeArguments[0].FullName() == "System.IServiceProvider") { hasFetch = true; ITypeSymbol funcReturn = asyncReturn.TypeArguments[1]; if (funcReturn.FullName() == "System.Threading.Tasks.Task") { configType = null; isFetchAsync = true; } else if (funcReturn is INamedTypeSymbol { IsGenericType : true } namedFuncReturn&& namedFuncReturn.ConstructedFrom.FullName() == "System.Threading.Tasks.Task<TResult>") { configType = namedFuncReturn.TypeArguments[0].FullName(); isFetchAsync = true; } else { configType = funcReturn.FullName(); isFetchAsync = false; } } else { return; } }