public override IEnumerable <StatementSyntax> GenerateCode(CsCallable csElement, PlatformDetectionType platform) { var interopSig = csElement.InteropSignatures[platform]; if (!interopSig.ForcedReturnBufferSig && csElement.HasReturnTypeValue) { foreach (var statement in GenerateProlog(csElement.ReturnValue, null, null)) { yield return(statement); } } foreach (var signatureParameter in interopSig.ParameterTypes) { var publicParameter = signatureParameter.Item; var nativeParameter = IdentifierName(signatureParameter.Name); var interopTypeSyntax = signatureParameter.InteropTypeSyntax; var builder = GetPrologBuilder(publicParameter); foreach (var statement in builder(publicParameter, nativeParameter, interopTypeSyntax)) { yield return(statement); } } }
public override IEnumerable <MemberDeclarationSyntax> GenerateCode(CsCallable csElement, PlatformDetectionType platform) { var sig = csElement.InteropSignatures[platform]; var delegateDecl = GenerateDelegateDeclaration(csElement, platform, sig); if (csElement is CsMethod { IsFunctionPointerInVtbl : true })
public ExpressionSyntax VTableOffsetExpression(PlatformDetectionType platform) { int windowsOffset = WindowsOffset, offset = Offset; return(GeneratorHelpers.PlatformSpecificExpression( Ioc.GlobalNamespace, platform, () => offset != windowsOffset, () => LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(windowsOffset)), () => LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(offset)) )); }
private ExpressionSyntax GetMarshalFunctionPointerForDelegate(CsMethod method, PlatformDetectionType platform) => InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GlobalNamespace.GetTypeNameSyntax(BuiltinType.Marshal), IdentifierName("GetFunctionPointerForDelegate") ), ArgumentList(SingletonSeparatedList(Argument(IdentifierName(GetMethodCacheName(method, platform))))) );
private static void CoercePlatform(CsMethod csMethod, ref PlatformDetectionType platform) { var interopSignatures = csMethod.InteropSignatures; if (interopSignatures.ContainsKey(platform)) { return; } platform = PlatformDetectionType.Any; Debug.Assert(interopSignatures.ContainsKey(platform)); }
private void InitSignatureWithReturnType(CsCallable callable, InteropMethodSignature cSharpInteropCalliSignature, PlatformDetectionType platform) { var returnType = CoerceToBlittable(GetInteropTypeForReturnValue(callable.ReturnValue, platform)); if (returnType is null) { Logger.Error(LoggingCodes.InvalidMethodReturnType, "Invalid return type {0} for method {1}", callable.ReturnValue.PublicType.QualifiedName, callable.CppElement); returnType = callable.ReturnValue.PublicType.QualifiedName; } cSharpInteropCalliSignature.ReturnType = returnType; }
private InteropMethodSignature GetNativeInteropSignature(CsCallable callable, bool isFunction, PlatformDetectionType platform) { // Tag if the method is a function var cSharpInteropCalliSignature = new InteropMethodSignature { IsFunction = isFunction, CallingConvention = callable.CppCallingConvention }; InitSignatureWithReturnType(callable, cSharpInteropCalliSignature, platform); // Handle Parameters InitCalliSignatureParameters(callable, cSharpInteropCalliSignature); return(cSharpInteropCalliSignature); }
private InteropType GetInteropTypeForReturnValue(CsReturnValue returnValue, PlatformDetectionType platform, ref InteropMethodSignatureFlags flags) { var platformSpecificReturnTypeOverrides = (platform & PlatformDetectionType.Windows) != 0 ? windowsOnlyReturnTypeOverrides : systemvOnlyReturnTypeOverrides; // Handle Return Type parameter // MarshalType.Type == null, then check that it is a structure if (returnValue.PublicType is CsStruct or CsEnum) { var returnQualifiedName = returnValue.PublicType.QualifiedName; if (returnTypeOverrides.TryGetValue(returnQualifiedName, out var interopType)) { flags |= interopType.SetFlags; return(interopType.NewType); } if (platformSpecificReturnTypeOverrides.TryGetValue(returnQualifiedName, out interopType)) { flags |= interopType.SetFlags; return(interopType.NewType); } return(returnValue.HasNativeValueType ? $"{returnValue.MarshalType.QualifiedName}.__Native" : returnValue.MarshalType.QualifiedName); } if (returnValue.MarshalType is CsFundamentalType fundamentalReturn) { return(fundamentalReturn); } if (returnValue.HasPointer) { return(returnValue.IsInterface ? TypeRegistry.IntPtr : TypeRegistry.VoidPtr); } return(null); }
public static string GetPlatformSpecificSuffix(PlatformDetectionType platform) { if (platform == PlatformDetectionType.Any) { return("_"); } StringBuilder str = new StringBuilder("_"); foreach (PlatformDetectionType flag in platforms) { if ((platform & flag) == flag && flag != PlatformDetectionType.Any) { str.Append(flag); str.Append('_'); } } return(str.ToString()); }
public override IEnumerable <MemberDeclarationSyntax> GenerateCode( CsFunction csElement, PlatformDetectionType platform) { var sig = csElement.InteropSignatures[platform]; yield return(MethodDeclaration( sig.ReturnTypeSyntax, $"{csElement.CppElementName}{GeneratorHelpers.GetPlatformSpecificSuffix(platform)}" ) .WithModifiers(ModifierList) .WithAttributeLists( SingletonList( AttributeList( SingletonSeparatedList( Attribute( DllImportName) .WithArgumentList( AttributeArgumentList( SeparatedList( new[] { AttributeArgument(IdentifierName(csElement.DllName)), AttributeArgument( LiteralExpression( SyntaxKind.StringLiteralExpression, Literal(csElement.CppElementName))) .WithNameEquals( NameEquals(IdentifierName("EntryPoint"))), AttributeArgument( ModelUtilities .GetManagedCallingConventionExpression( csElement.CppCallingConvention)) .WithNameEquals( NameEquals(IdentifierName("CallingConvention"))) }))))))) .WithParameterList( ParameterList( SeparatedList( sig.ParameterTypes.Select( param => Parameter(Identifier(param.Name)) .WithType(param.InteropTypeSyntax))))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); }
private void InitSignatureWithReturnType(CsCallable callable, InteropMethodSignature cSharpInteropCalliSignature, PlatformDetectionType platform) { InteropMethodSignatureFlags flags = default; var returnType = GetInteropTypeForReturnValue(callable.ReturnValue, platform, ref flags); if (returnType == null) { logger.Error(LoggingCodes.InvalidMethodReturnType, "Invalid return type {0} for method {1}", callable.ReturnValue.PublicType.QualifiedName, callable.CppElement); returnType = callable.ReturnValue.PublicType.QualifiedName; } if (flags != default) { cSharpInteropCalliSignature.Flags |= flags; } cSharpInteropCalliSignature.ReturnType = returnType; }
public static string GetPlatformSpecificSuffix(PlatformDetectionType platform) { if (platform == PlatformDetectionType.Any) { return("_"); } StringBuilder str = new("_", PlatformsNoAnyStringLength); foreach (var flag in PlatformsNoAny) { if ((platform & flag) != flag) { continue; } str.Append(flag); str.Append('_'); } return(str.ToString()); }
private DelegateDeclarationSyntax GenerateDelegateDeclaration(CsCallable csElement, PlatformDetectionType platform, InteropMethodSignature sig) { return(DelegateDeclaration(ParseTypeName(sig.ReturnType.TypeName), VtblGenerator.GetMethodDelegateName(csElement, platform)) .AddAttributeLists( AttributeList( SingletonSeparatedList( Attribute( ParseName("System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute")) .AddArgumentListArguments( AttributeArgument( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, IdentifierName("System"), IdentifierName("Runtime")), IdentifierName("InteropServices")), IdentifierName("CallingConvention")), IdentifierName(sig.CallingConvention.ToManagedCallingConventionName()))))))) .WithParameterList( ParameterList( (csElement is CsMethod ? SingletonSeparatedList( Parameter(Identifier("thisObject")) .WithType(ParseTypeName("System.IntPtr"))) : default)
public abstract StatementSyntax GenerateCode(T csElement, PlatformDetectionType platform);
public override bool Execute() { var documentationFiles = new Dictionary <string, XmlDocument>(); foreach (var file in ExternalDocumentation ?? Enumerable.Empty <ITaskItem>()) { using (var stream = File.OpenRead(file.ItemSpec)) { var xml = new XmlDocument(); xml.Load(stream); documentationFiles.Add(file.ItemSpec, xml); } } var globalNamespace = new GlobalNamespaceProvider(); foreach (var nameOverride in GlobalNamespaceOverrides ?? Enumerable.Empty <ITaskItem>()) { var wellKnownName = nameOverride.ItemSpec; var overridenName = nameOverride.GetMetadata("Override"); if (overridenName != null && Enum.TryParse(wellKnownName, out WellKnownName name)) { globalNamespace.OverrideName(name, overridenName); } } PlatformDetectionType platformMask = 0; foreach (var platform in Platforms ?? Enumerable.Empty <ITaskItem>()) { if (!Enum.TryParse <PlatformDetectionType>("Is" + platform.ItemSpec, out var parsedPlatform)) { Log.LogWarning(null, LoggingCodes.InvalidPlatformDetectionType, null, null, 0, 0, 0, 0, $"The platform type {platform} is an unknown platform to SharpGenTools. Falling back to Any platform detection."); platformMask = PlatformDetectionType.Any; } else { platformMask |= parsedPlatform; } } if (platformMask == 0) { platformMask = PlatformDetectionType.Any; } var config = new GeneratorConfig { Platforms = platformMask }; var generator = new RoslynGenerator( new Logger(new MSBuildSharpGenLogger(Log), null), globalNamespace, new CachedDocumentationLinker(DocLinkCache.ItemSpec), new ExternalDocCommentsReader(documentationFiles), config); generator.Run(CsAssembly.Read(Model.ItemSpec), GeneratedCodeFolder); return(true); }
public abstract MemberDeclarationSyntax GenerateCode(T csElement, PlatformDetectionType platform);
public abstract IEnumerable <StatementSyntax> GenerateCode(T csElement, PlatformDetectionType platform);
protected override ExpressionSyntax Generate(CsCallable callable, PlatformDetectionType platform) { var interopSig = callable.InteropSignatures[platform]; var interopReturnType = interopSig.ReturnTypeSyntax; var arguments = IterateNativeArguments(callable is CsMethod, interopSig).ToArray(); var vtblAccess = callable switch { CsMethod method => ElementAccessExpression( ThisExpression(), BracketedArgumentList( SingletonSeparatedList( Argument( method.CustomVtbl ? MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName($"{callable.Name}__vtbl_index") ) : method.VTableOffsetExpression(platform) ) ) ) ), _ => null }; ExpressionSyntax FnPtrCall() { var fnptrParameters = arguments .Select(x => x.Type) .Append(interopReturnType) .Select(FunctionPointerParameter); return(GeneratorHelpers.CastExpression( FunctionPointerType( FunctionPointerCallingConvention( Token(SyntaxKind.UnmanagedKeyword), FunctionPointerUnmanagedCallingConventionList( SingletonSeparatedList( FunctionPointerUnmanagedCallingConvention( Identifier(callable.CppCallingConvention.ToCallConvShortName()) ) ) ) ), FunctionPointerParameterList(SeparatedList(fnptrParameters)) ), vtblAccess )); } var what = callable switch { CsFunction => IdentifierName( callable.CppElementName + GeneratorHelpers.GetPlatformSpecificSuffix(platform) ), CsMethod => GeneratorHelpers.WrapInParentheses(FnPtrCall()), _ => throw new ArgumentOutOfRangeException() }; ExpressionSyntax call = InvocationExpression( what, ArgumentList(SeparatedList(arguments.Select(x => x.Argument))) ); if (interopSig.ForcedReturnBufferSig || !callable.HasReturnType) { return(call); } var generatesMarshalVariable = GetMarshaller(callable.ReturnValue).GeneratesMarshalVariable(callable.ReturnValue); var publicTypeSyntax = ReverseCallablePrologCodeGenerator.GetPublicType(callable.ReturnValue); if (callable.HasReturnTypeValue && !generatesMarshalVariable && !publicTypeSyntax.IsEquivalentTo(interopSig.ReturnTypeSyntax)) { call = CastExpression(publicTypeSyntax, call); } return(AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, generatesMarshalVariable ? MarshallerBase.GetMarshalStorageLocation(callable.ReturnValue) : IdentifierName(callable.ReturnValue.Name), call )); }
private static StatementSyntax PlatformSpecificStatement(GlobalNamespaceProvider globalNamespace, PlatformDetectionType allPlatformBitmap, PlatformDetectionType platform, StatementSyntax statement) { if ((platform & allPlatformBitmap) == allPlatformBitmap) { return(statement); } ExpressionSyntax condition = null; foreach (PlatformDetectionType flag in platforms) { if ((platform & flag) == flag && flag != PlatformDetectionType.Any) { var newCondition = MemberAccessExpression( Microsoft.CodeAnalysis.CSharp.SyntaxKind.SimpleMemberAccessExpression, globalNamespace.GetTypeNameSyntax(WellKnownName.PlatformDetection), IdentifierName(flag.ToString())); condition = condition is null ? (ExpressionSyntax)newCondition : BinaryExpression(Microsoft.CodeAnalysis.CSharp.SyntaxKind.LogicalAndExpression, condition, newCondition); } } return(condition is null ? statement : IfStatement( condition, statement)); }
public ExpressionSyntax GenerateCall(CsCallable callable, PlatformDetectionType platform, InteropMethodSignature interopSig) { var arguments = IterateNativeArguments(callable, interopSig).ToArray(); ElementAccessExpressionSyntax vtblAccess = null; if (callable is CsMethod method) { var windowsOffsetExpression = LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(method.WindowsOffset)); var nonWindowsOffsetExpression = LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(method.Offset)); ExpressionSyntax vtableOffsetExpression; if ((platform & PlatformDetectionType.Any) == PlatformDetectionType.Any && method.Offset != method.WindowsOffset) { vtableOffsetExpression = ConditionalExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GlobalNamespace.GetTypeNameSyntax(WellKnownName.PlatformDetection), IdentifierName("Is" + nameof(PlatformDetectionType.Windows))), windowsOffsetExpression, nonWindowsOffsetExpression); } else if ((platform & PlatformDetectionType.Windows) != 0) { vtableOffsetExpression = windowsOffsetExpression; } else { vtableOffsetExpression = nonWindowsOffsetExpression; } vtblAccess = ElementAccessExpression( ThisExpression(), BracketedArgumentList( SingletonSeparatedList( Argument( method.CustomVtbl ? MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName($"{callable.Name}__vtbl_index") ) : vtableOffsetExpression ) ) ) ); } ExpressionSyntax FnPtrCall() { var fnptrParameters = arguments .Select(x => x.Type) .Append(ParseTypeName(interopSig.ReturnType.TypeName)) .Select(FunctionPointerParameter); return(GeneratorHelpers.CastExpression( FunctionPointerType( FunctionPointerCallingConvention( Token(SyntaxKind.UnmanagedKeyword), FunctionPointerUnmanagedCallingConventionList( SingletonSeparatedList( FunctionPointerUnmanagedCallingConvention( Identifier(callable.CppCallingConvention.ToCallConvShortName()) ) ) ) ), FunctionPointerParameterList(SeparatedList(fnptrParameters)) ), vtblAccess )); } var what = callable switch { CsFunction => IdentifierName( callable.CppElementName + GeneratorHelpers.GetPlatformSpecificSuffix(platform) ), CsMethod => GeneratorHelpers.WrapInParentheses(FnPtrCall()), _ => throw new ArgumentOutOfRangeException() }; ExpressionSyntax call = InvocationExpression( what, ArgumentList(SeparatedList(arguments.Select(x => x.Argument))) ); if (interopSig.CastToNativeLong) { call = CastExpression(GlobalNamespace.GetTypeNameSyntax(WellKnownName.NativeLong), call); } if (interopSig.CastToNativeULong) { call = CastExpression(GlobalNamespace.GetTypeNameSyntax(WellKnownName.NativeULong), call); } if (interopSig.ForcedReturnBufferSig || !callable.HasReturnType) { return(call); } return(AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, GetMarshaller(callable.ReturnValue).GeneratesMarshalVariable(callable.ReturnValue) ? MarshallerBase.GetMarshalStorageLocation(callable.ReturnValue) : IdentifierName(callable.ReturnValue.Name), call )); }
private void InitSignatureWithReturnType(CsCallable callable, InteropMethodSignature cSharpInteropCalliSignature, PlatformDetectionType platform) { Debug.Assert((platform & (PlatformDetectionType.IsWindows | PlatformDetectionType.IsItaniumSystemV)) != (PlatformDetectionType.IsWindows | PlatformDetectionType.IsItaniumSystemV) || !callable.IsReturnStructLarge); var platformSpecificReturnTypeOverrides = (platform & PlatformDetectionType.IsWindows) != 0 ? windowsOnlyReturnTypeOverrides : systemvOnlyReturnTypeOverrides; // Handle Return Type parameter // MarshalType.Type == null, then check that it is a structure if (callable.ReturnValue.PublicType is CsStruct || callable.ReturnValue.PublicType is CsEnum) { var returnQualifiedName = callable.ReturnValue.PublicType.QualifiedName; if (returnTypeOverrides.TryGetValue(returnQualifiedName, out var interopType)) { cSharpInteropCalliSignature.ReturnType = interopType; } else if (platformSpecificReturnTypeOverrides.TryGetValue(returnQualifiedName, out interopType)) { cSharpInteropCalliSignature.ReturnType = interopType; } else if (callable.ReturnValue.HasNativeValueType) { cSharpInteropCalliSignature.ReturnType = $"{callable.ReturnValue.MarshalType.QualifiedName}.__Native"; } else { cSharpInteropCalliSignature.ReturnType = callable.ReturnValue.MarshalType.QualifiedName; } } else if (callable.ReturnValue.MarshalType is CsFundamentalType fundamentalReturn) { cSharpInteropCalliSignature.ReturnType = fundamentalReturn.Type; } else if (callable.ReturnValue.HasPointer) { if (callable.ReturnValue.IsInterface) { cSharpInteropCalliSignature.ReturnType = typeof(IntPtr); } else { cSharpInteropCalliSignature.ReturnType = typeof(void *); } } else { cSharpInteropCalliSignature.ReturnType = callable.ReturnValue.PublicType.QualifiedName; logger.Error(LoggingCodes.InvalidMethodReturnType, "Invalid return type {0} for method {1}", callable.ReturnValue.PublicType.QualifiedName, callable.CppElement); } }
public abstract IEnumerable <MemberDeclarationSyntax> GenerateCode(T csElement, PlatformDetectionType platform);
StatementSyntax IPlatformSingleCodeGenerator <T, StatementSyntax> .GenerateCode( T csElement, PlatformDetectionType platform ) => Generate(csElement, platform) is {
protected abstract IEnumerable <ExpressionSyntax> Generate(T csElement, PlatformDetectionType platform);
IEnumerable <StatementSyntax> IPlatformMultiCodeGenerator <T, StatementSyntax> .GenerateCode( T csElement, PlatformDetectionType platform ) => Generate(csElement, platform) .Where(static x => x != null)
private bool Execute(ConfigFile config) { config.GetFilesWithIncludesAndExtensionHeaders( out var configsWithHeaders, out var configsWithExtensionHeaders ); var cppHeaderGenerator = new CppHeaderGenerator(SharpGenLogger, OutputPath); var cppHeaderGenerationResult = cppHeaderGenerator.GenerateCppHeaders(config, configsWithHeaders, configsWithExtensionHeaders); if (SharpGenLogger.HasErrors) { return(false); } var resolver = new IncludeDirectoryResolver(SharpGenLogger); resolver.Configure(config); var castXml = new CastXmlRunner(SharpGenLogger, resolver, CastXmlExecutable.ItemSpec, CastXmlArguments) { OutputPath = OutputPath }; var macroManager = new MacroManager(castXml); var cppExtensionGenerator = new CppExtensionHeaderGenerator(); var module = config.CreateSkeletonModule(); macroManager.Parse(Path.Combine(OutputPath, config.HeaderFileName), module); cppExtensionGenerator.GenerateExtensionHeaders( config, OutputPath, module, configsWithExtensionHeaders, cppHeaderGenerationResult.UpdatedConfigs ); GenerateInputsCache( macroManager.IncludedFiles .Concat(config.ConfigFilesLoaded.Select(x => x.AbsoluteFilePath)) .Concat(configsWithExtensionHeaders.Select(x => Path.Combine(OutputPath, x.ExtensionFileName))) .Select(s => Utilities.FixFilePath(s, Utilities.EmptyFilePathBehavior.Ignore)) .Where(x => x != null) .Distinct() ); if (SharpGenLogger.HasErrors) { return(false); } // Run the parser var parser = new CppParser(SharpGenLogger, config) { OutputPath = OutputPath }; if (SharpGenLogger.HasErrors) { return(false); } CppModule group; using (var xmlReader = castXml.Process(parser.RootConfigHeaderFileName)) { // Run the C++ parser group = parser.Run(module, xmlReader); } if (SharpGenLogger.HasErrors) { return(false); } config.ExpandDynamicVariables(SharpGenLogger, group); var docLinker = new DocumentationLinker(); var typeRegistry = new TypeRegistry(SharpGenLogger, docLinker); var namingRules = new NamingRulesManager(); var globalNamespace = new GlobalNamespaceProvider(); foreach (var nameOverride in GlobalNamespaceOverrides) { var wellKnownName = nameOverride.ItemSpec; var overridenName = nameOverride.GetMetadata("Override"); if (string.IsNullOrEmpty(overridenName)) { continue; } if (Enum.TryParse(wellKnownName, out WellKnownName name)) { globalNamespace.OverrideName(name, overridenName); } else { SharpGenLogger.Warning( LoggingCodes.InvalidGlobalNamespaceOverride, "Invalid override of \"{0}\": unknown class name, ignoring the override.", wellKnownName ); } } // Run the main mapping process var transformer = new TransformManager( globalNamespace, namingRules, SharpGenLogger, typeRegistry, docLinker, new ConstantManager(namingRules, docLinker) ); var(solution, defines) = transformer.Transform(group, config); var consumerConfig = new ConfigFile { Id = ConsumerBindMappingConfigId, IncludeProlog = { cppHeaderGenerationResult.Prologue }, Extension = new List <ExtensionBaseRule>(defines) }; var(bindings, generatedDefines) = transformer.GenerateTypeBindingsForConsumers(); consumerConfig.Bindings.AddRange(bindings); consumerConfig.Extension.AddRange(generatedDefines); consumerConfig.Mappings.AddRange( docLinker.GetAllDocLinks().Select( link => new MappingRule { DocItem = link.cppName, MappingNameFinal = link.cSharpName } ) ); GenerateConfigForConsumers(consumerConfig); if (SharpGenLogger.HasErrors) { return(false); } var documentationCacheItemSpec = DocumentationCache.ItemSpec; Utilities.RequireAbsolutePath(documentationCacheItemSpec, nameof(DocumentationCache)); var cache = File.Exists(documentationCacheItemSpec) ? DocItemCache.Read(documentationCacheItemSpec) : new DocItemCache(); DocumentationLogger docLogger = new(SharpGenLogger) { MaxLevel = LogLevel.Warning }; var docContext = new Lazy <DocumentationContext>(() => new DocumentationContext(docLogger)); ExtensibilityDriver.Instance.DocumentModule(SharpGenLogger, cache, solution, docContext).Wait(); if (docContext.IsValueCreated) { Regex[] silencePatterns = null; var docLogLevelDefault = DocumentationFailuresAsErrors ? LogLevel.Error : LogLevel.Warning; foreach (var queryFailure in docContext.Value.Failures) { if (silencePatterns == null) { silencePatterns = new Regex[SilenceMissingDocumentationErrorIdentifierPatterns.Length]; for (var i = 0; i < silencePatterns.Length; i++) { silencePatterns[i] = new Regex( SilenceMissingDocumentationErrorIdentifierPatterns[i].ItemSpec, RegexOptions.CultureInvariant ); } } if (silencePatterns.Length != 0) { bool SilencePredicate(Regex x) => x.Match(queryFailure.Query).Success; if (silencePatterns.Any(SilencePredicate)) { continue; } } var providerName = queryFailure.FailedProviderName ?? "<null>"; var docLogLevel = queryFailure.TreatProviderFailuresAsErrors ? docLogLevelDefault : docLogLevelDefault > LogLevel.Warning ? LogLevel.Warning : docLogLevelDefault; if (queryFailure.Exceptions == null || queryFailure.Exceptions.Count <= 1) { SharpGenLogger.LogRawMessage( docLogLevel, LoggingCodes.DocumentationProviderInternalError, "Documentation provider [{0}] query for \"{1}\" failed.", queryFailure.Exceptions?.FirstOrDefault(), providerName, queryFailure.Query ); } else { var exceptionsCount = queryFailure.Exceptions.Count; for (var index = 0; index < exceptionsCount; index++) { var exception = queryFailure.Exceptions[index]; SharpGenLogger.LogRawMessage( docLogLevel, LoggingCodes.DocumentationProviderInternalError, "Documentation provider [{0}] query for \"{1}\" failed ({2}/{3}).", exception, providerName, queryFailure.Query, index + 1, exceptionsCount ); } } } } cache.WriteIfDirty(documentationCacheItemSpec); if (SharpGenLogger.HasErrors) { return(false); } var documentationFiles = new Dictionary <string, XmlDocument>(); foreach (var file in ExternalDocumentation) { using var stream = File.OpenRead(file.ItemSpec); var xml = new XmlDocument(); xml.Load(stream); documentationFiles.Add(file.ItemSpec, xml); } PlatformDetectionType platformMask = 0; foreach (var platform in Platforms) { if (!Enum.TryParse <PlatformDetectionType>(platform.ItemSpec, out var parsedPlatform)) { SharpGenLogger.Warning( LoggingCodes.InvalidPlatformDetectionType, "The platform type {0} is an unknown platform to SharpGenTools. Falling back to Any platform detection.", platform ); platformMask = PlatformDetectionType.Any; } else { platformMask |= parsedPlatform; } } if (platformMask == 0) { platformMask = PlatformDetectionType.Any; } if (SharpGenLogger.HasErrors) { return(false); } var generator = new RoslynGenerator( SharpGenLogger, globalNamespace, docLinker, new ExternalDocCommentsReader(documentationFiles), new GeneratorConfig { Platforms = platformMask } ); generator.Run(solution, GeneratedCodeFolder); return(!SharpGenLogger.HasErrors); }
IEnumerable <ExpressionSyntax> IPlatformMultiCodeGenerator <T, ExpressionSyntax> .GenerateCode( T csElement, PlatformDetectionType platform ) => Generate(csElement, platform);
private FieldDeclarationSyntax DelegateCacheDecl(CsMethod method, PlatformDetectionType platform) => FieldDeclaration( default, TokenList(
internal static string GetMethodDelegateName(CsCallable csElement, PlatformDetectionType platform) => csElement.Name + "Delegate" + GeneratorHelpers.GetPlatformSpecificSuffix(platform);
ExpressionSyntax IPlatformSingleCodeGenerator <T, ExpressionSyntax> .GenerateCode( T csElement, PlatformDetectionType platform ) => Generate(csElement, platform);