Exemplo n.º 1
0
        protected CppModule ParseCpp(ConfigFile config)
        {
            var loaded = ConfigFile.Load(config, new string[0], Logger);

            loaded.GetFilesWithIncludesAndExtensionHeaders(out var configsWithIncludes,
                                                           out var configsWithExtensionHeaders);

            var cppHeaderGenerator = new CppHeaderGenerator(Logger, TestDirectory.FullName);

            var updated = cppHeaderGenerator
                          .GenerateCppHeaders(loaded, configsWithIncludes, configsWithExtensionHeaders)
                          .UpdatedConfigs;

            var castXml = GetCastXml(loaded);

            var macro = new MacroManager(castXml);
            var extensionGenerator = new CppExtensionHeaderGenerator();

            var skeleton = loaded.CreateSkeletonModule();

            macro.Parse(Path.Combine(TestDirectory.FullName, loaded.HeaderFileName), skeleton);

            extensionGenerator.GenerateExtensionHeaders(
                loaded, TestDirectory.FullName, skeleton, configsWithExtensionHeaders, updated
                );

            var parser = new CppParser(Logger, loaded)
            {
                OutputPath = TestDirectory.FullName
            };

            using var xmlReader = castXml.Process(parser.RootConfigHeaderFileName);

            return(parser.Run(skeleton, xmlReader));
        }
Exemplo n.º 2
0
        public void MacroManagerCollectsIncludedHeaders()
        {
            CreateCppFile("included", "");

            var includeRule = GetTestFileIncludeRule();

            var config = new ConfigFile
            {
                Id          = nameof(MacroManagerCollectsIncludedHeaders),
                Namespace   = nameof(MacroManagerCollectsIncludedHeaders),
                IncludeDirs = { includeRule },
                Includes    =
                {
                    CreateCppFile("includer", "#include \"included.h\"")
                }
            };

            var castXml = GetCastXml(ConfigFile.Load(config, Array.Empty <string>(), Logger));

            var macroManager = new MacroManager(castXml);

            macroManager.Parse(Path.Combine(includeRule.Path, "includer.h"), new CppModel.CppModule());

            Assert.Contains(includeRule.Path + "/included.h",
                            macroManager.IncludedFiles);
        }
Exemplo n.º 3
0
    protected CppModule ParseCpp(ConfigFile config)
    {
        config.Load(null, Array.Empty <string>(), Logger);

        config.GetFilesWithIncludesAndExtensionHeaders(out var configsWithIncludes,
                                                       out var configsWithExtensionHeaders);

        CppHeaderGenerator cppHeaderGenerator = new(TestDirectory.FullName, Ioc);

        var updated = cppHeaderGenerator
                      .GenerateCppHeaders(config, configsWithIncludes, configsWithExtensionHeaders)
                      .UpdatedConfigs;

        var castXml = GetCastXml(config);

        var macro = new MacroManager(castXml);
        var extensionGenerator = new CppExtensionHeaderGenerator();

        var skeleton = config.CreateSkeletonModule();

        macro.Parse(Path.Combine(TestDirectory.FullName, config.HeaderFileName), skeleton);

        extensionGenerator.GenerateExtensionHeaders(
            config, TestDirectory.FullName, skeleton, configsWithExtensionHeaders, updated
            );

        CppParser parser = new(config, Ioc)
        {
            OutputPath = TestDirectory.FullName
        };

        using var xmlReader = castXml.Process(parser.RootConfigHeaderFileName);

        return(parser.Run(skeleton, xmlReader));
    }
}
Exemplo n.º 4
0
        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);
        }