in SharpGenTools.Sdk/Tasks/SharpGenTask.cs [67:332]
private bool Execute(ConfigFile config)
{
config.GetFilesWithIncludesAndExtensionHeaders(
out var configsWithHeaders,
out var configsWithExtensionHeaders
);
CppHeaderGenerator cppHeaderGenerator = new(OutputPath, ioc);
var cppHeaderGenerationResult = cppHeaderGenerator.GenerateCppHeaders(config, configsWithHeaders, configsWithExtensionHeaders);
if (AbortExecution)
return false;
IncludeDirectoryResolver resolver = new(ioc);
resolver.Configure(config);
CastXmlRunner castXml = new(resolver, CastXmlExecutable.ItemSpec, CastXmlArguments, ioc)
{
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 (AbortExecution)
return false;
// Run the parser
var parser = new CppParser(config, ioc)
{
OutputPath = OutputPath
};
if (AbortExecution)
return false;
CppModule group;
using (var xmlReader = castXml.Process(parser.RootConfigHeaderFileName))
{
// Run the C++ parser
group = parser.Run(module, xmlReader);
}
if (AbortExecution)
return false;
config.ExpandDynamicVariables(SharpGenLogger, group);
var docLinker = ioc.DocumentationLinker;
var globalNamespace = ioc.GlobalNamespace;
NamingRulesManager namingRules = new();
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
TransformManager transformer = new(
namingRules,
new ConstantManager(namingRules, ioc),
ioc
);
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 (AbortExecution)
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 (AbortExecution)
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 (AbortExecution)
return false;
serviceContainer.AddService(new ExternalDocCommentsReader(documentationFiles));
serviceContainer.AddService<IGeneratorRegistry>(
new DefaultGenerators(
new GeneratorConfig
{
Platforms = platformMask
},
ioc
)
);
RoslynGenerator generator = new();
generator.Run(solution, GeneratedCodeFolder, ioc);
return !SharpGenLogger.HasErrors;
}