public (SourceText?source, IReadOnlyList <Diagnostic> diagnostics) CreateImplementation(INamedTypeSymbol namedTypeSymbol) { // If we've got any symbols errors from just instantiating it, we're going to have a bad time. Give up now. if (this.symbolsDiagnosticReporter.HasErrors) { return(null, Array.Empty <Diagnostic>()); } var diagnosticReporter = new DiagnosticReporter(); var analyzer = new RoslynTypeAnalyzer(this.compilation, namedTypeSymbol, this.wellKnownSymbols, this.attributeInstantiator, diagnosticReporter); var typeModel = analyzer.Analyze(); var generator = new ImplementationGenerator(typeModel, this.emitter, diagnosticReporter); var emittedType = generator.Generate(); // If there are symbols diagnostic errors, we have to fail this type. // However, we'll then clear the symbols diagnostics, so we can move onto the next type // (which might succeed). // We'll report the symbols diagnostics in one go at the end. We might well end up with duplicates // (WellKnownSymbols will keep reporting the same diagnostics), so use a HashSet. this.symbolsDiagnostics.UnionWith(this.symbolsDiagnosticReporter.Diagnostics); bool hasSymbolsErrors = this.symbolsDiagnosticReporter.HasErrors; this.symbolsDiagnosticReporter.Clear(); return(hasSymbolsErrors || diagnosticReporter.HasErrors ? null : emittedType.SourceText, diagnosticReporter.Diagnostics); }
private void GenerateAndAssertSnapshot( string patternInterfaceFile, string patternImplementationFile, string declarationInterfaceFile, string targetNameSpace, string implName, string snapshotName) { this.LoadWorkSpace( patternInterfaceFile, patternImplementationFile, declarationInterfaceFile, out var itfDeclaration, out var itfPatternDeclaration, out var implPatternDeclaration); var locator = new RelativeLocator(string.Empty, targetNameSpace); var snapshotGenerator = new SnapshotGenerator(); var implGenerator = new ImplementationGenerator( snapshotGenerator, locator, itfPatternDeclaration, implPatternDeclaration); var writerSelector = SetupWriterSelector(itfPatternDeclaration, implPatternDeclaration, itfDeclaration, implName); implGenerator.Generate(writerSelector, itfDeclaration, implName); string location = SnapshotHelper.GetLocationFromCallingProjectRoot("Generator"); SnapshotHelper.AssertSnapshot(snapshotGenerator.GetAllGenerated(), snapshotName, location); }
public CilDocumentSyntax Build(ILogging logging, CilDocumentSyntax context) { if (data == null) { logging.Write( new LogEntry { Severity = Severity.Error, Message = string.Format( "Failed to compile '{0}' language definition.", languageName.FullLanguageName), Origin = languageName.Origin }); return(null); } this.logging = logging; this.declaringTypeRef = context.Types.Class_( ClassName.Parse(languageName.LanguageTypeName)); logging.Write( new LogEntry { Severity = Severity.Verbose, Message = string.Format("Started Compiling Derived assembly for {0}", languageName.FullLanguageName) }); var result = context .Class_() .Public .Named(languageName.LanguageTypeName) .Extends(context.Types.Import(typeof(LanguageBase))) .Do(BuildMethod_CreateGrammar) .Do(BuildMethod_GetParserAction) .Do(BuildMethod_CreateTokenIdentities) .Do(BuildMethod_Scan1) .Do(BuildMethod_TermFactory) .Do(BuildMethod_GrammarAction) .Do(BuildMethod_MergeAction) .Do(BuildMethod_CreateStateToSymbol) .Do(BuildMethod_CreateParserActionConflicts) .Do(BuildMethod_CreateTokenComplexityTable) .Do(BuildMethod_CreateDefaultContext) .Do(Build_Ctor) .EndClass() ; logging.Write( new LogEntry { Severity = Severity.Verbose, Message = string.Format("Done Compiling Derived assembly for {0}", languageName.FullLanguageName) }); implementationGenerator.Generate(context); return(result); }
/// <summary> /// Process the generator. /// </summary> /// <param name="projectFile">The project file to work from.</param> public void Generate(string projectFile) { this.logger.LogInformation($"Loading {Path.GetFileName(projectFile)}..."); var projectFolder = Path.GetDirectoryName(projectFile); // First we need to register the project. var project = this.workspace.RegisterProject(projectFile); // Register the pattern interface. var patternInterfaceDeclaration = this.workspace.RegisterFile("./Patterns/Itf/IModelPattern.cs") .Declarations.Single() as IInterfaceDeclaration; // Register the pattern implementation. var patternImplementationDeclaration = this.workspace.RegisterFile("./Patterns/Impl/ModelPattern.cs") .Declarations.Single() as IGenericDeclaration <SyntaxNode>; // Load the project and its project dependencies. (Note that for now we only load the sources. // The binary assembly dependencies are not taken into account) var resolver = this.workspace.DeepLoad(); // Get the base interface in order to find all extended interfaces that need to be implemented. var modelBaseInterface = resolver.Find("SoloX.GeneratorTools.Core.CSharp.Examples.Core.IModelBase").Single() as IGenericDeclaration <SyntaxNode>; // Setup a locator that will tell the location where the generated classes must be written. var locator = new RelativeLocator(projectFolder, project.RootNameSpace, suffix: "Impl"); // Create the Implementation Generator with a file generator, the locator and the pattern interface/class. var generator = new ImplementationGenerator( new FileGenerator(".generated.cs"), locator, patternInterfaceDeclaration, patternImplementationDeclaration); // Loop on all interface extending the base interface. foreach (var modelInterface in modelBaseInterface.ExtendedBy.Where(d => d != patternInterfaceDeclaration)) { this.logger.LogInformation(modelInterface.FullName); var implName = GeneratorHelper.ComputeClassName(modelInterface.Name); // Create the property writer what will use all properties from the model interface to generate // and write the corresponding code depending on the given patterns. var propertyWriter = new PropertyWriter( patternInterfaceDeclaration.Properties.Single(), modelInterface.Properties); // Setup some basic text replacement writer. var itfNameWriter = new StringReplaceWriter(patternInterfaceDeclaration.Name, modelInterface.Name); var implNameWriter = new StringReplaceWriter(patternImplementationDeclaration.Name, implName); // Create the writer selector. var writerSelector = new WriterSelector(propertyWriter, itfNameWriter, implNameWriter); // And generate the class implementation. generator.Generate(writerSelector, (IInterfaceDeclaration)modelInterface, implName); } }