private static void Parse(ParseResult disco, CSharpCompilation compilation, SyntaxTree tree) { var model = compilation.GetSemanticModel(tree); //we quite probably have errors but that is normal //var diags = model.GetDiagnostics(); var classDecls = tree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>(); foreach (var classSymbol in classDecls.Select(x => model.GetDeclaredSymbol(x))) { ParseClassSymbols(disco, classSymbol); var baseClassSymbol = classSymbol.BaseType; if (baseClassSymbol != null) //disco.SetContentBaseClass(SymbolDisplay.ToDisplayString(classSymbol), SymbolDisplay.ToDisplayString(baseClassSymbol)); disco.SetContentBaseClass(classSymbol.Name, baseClassSymbol.Name); var interfaceSymbols = classSymbol.Interfaces; disco.SetContentInterfaces(classSymbol.Name, //SymbolDisplay.ToDisplayString(classSymbol), interfaceSymbols.Select(x => x.Name)); //SymbolDisplay.ToDisplayString(x))); var hasCtor = classSymbol.Constructors .Any(x => { if (x.IsStatic) return false; if (x.Parameters.Length != 1) return false; var type1 = x.Parameters[0].Type; var type2 = typeof (global::Umbraco.Core.Models.IPublishedContent); return type1.ToDisplayString() == type2.FullName; }); if (hasCtor) disco.SetHasCtor(classSymbol.Name); foreach (var propertySymbol in classSymbol.GetMembers().Where(x => x is IPropertySymbol)) ParsePropertySymbols(disco, classSymbol, propertySymbol); foreach (var staticMethodSymbol in classSymbol.GetMembers().Where(x => x is IMethodSymbol)) ParseMethodSymbol(disco, classSymbol, staticMethodSymbol); } var interfaceDecls = tree.GetRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>(); foreach (var interfaceSymbol in interfaceDecls.Select(x => model.GetDeclaredSymbol(x))) { ParseClassSymbols(disco, interfaceSymbol); var interfaceSymbols = interfaceSymbol.Interfaces; disco.SetContentInterfaces(interfaceSymbol.Name, //SymbolDisplay.ToDisplayString(interfaceSymbol), interfaceSymbols.Select(x => x.Name)); // SymbolDisplay.ToDisplayString(x))); } ParseAssemblySymbols(disco, compilation.Assembly); }
/// <summary> /// Initializes a new instance of the <see cref="Builder"/> class with a list of models to generate /// and the result of code parsing. /// </summary> /// <param name="typeModels">The list of models to generate.</param> /// <param name="parseResult">The result of code parsing.</param> protected Builder(IList<TypeModel> typeModels, ParseResult parseResult) { if (typeModels == null) throw new ArgumentNullException("typeModels"); if (parseResult == null) throw new ArgumentNullException("parseResult"); _typeModels = typeModels; ParseResult = parseResult; Prepare(); }
/// <summary> /// Parses a set of file. /// </summary> /// <param name="files">A set of (filename,content) representing content to parse.</param> /// <param name="referencedAssemblies">Assemblies to reference in compilations.</param> /// <returns>The result of the code parsing.</returns> /// <remarks>The set of files is a dictionary of name, content.</remarks> public ParseResult Parse(IDictionary<string, string> files, IEnumerable<Assembly> referencedAssemblies) { SyntaxTree[] trees; var compiler = new Compiler(Config.LanguageVersion); foreach (var asm in referencedAssemblies) compiler.ReferencedAssemblies.Add(asm); var compilation = compiler.GetCompilation("Umbraco.ModelsBuilder.Generated", files, out trees); var disco = new ParseResult(); foreach (var tree in trees) Parse(disco, compilation, tree); return disco; }
/// <summary> /// Initializes a new instance of the <see cref="Builder"/> class with a list of models to generate, /// the result of code parsing, and a models namespace. /// </summary> /// <param name="typeModels">The list of models to generate.</param> /// <param name="parseResult">The result of code parsing.</param> /// <param name="modelsNamespace">The models namespace.</param> protected Builder(IList<TypeModel> typeModels, ParseResult parseResult, string modelsNamespace) : this(typeModels, parseResult) { // can be null or empty, we'll manage ModelsNamespace = modelsNamespace; }
public TestBuilder(IList<TypeModel> typeModels, ParseResult parseResult) : base(typeModels, parseResult) { }
private static void ParseMethodSymbol(ParseResult disco, ISymbol classSymbol, ISymbol symbol) { var methodSymbol = symbol as IMethodSymbol; if (methodSymbol == null || !methodSymbol.IsStatic || methodSymbol.IsGenericMethod || methodSymbol.ReturnsVoid || methodSymbol.IsExtensionMethod || methodSymbol.Parameters.Length != 1) return; var returnType = methodSymbol.ReturnType; var paramSymbol = methodSymbol.Parameters[0]; var paramType = paramSymbol.Type; // cannot do this because maybe the param type is ISomething and we don't have // that type yet - will be generated - so cannot put any condition on it really //const string iPublishedContent = "Umbraco.Core.Models.IPublishedContent"; //var implements = paramType.AllInterfaces.Any(x => x.ToDisplayString() == iPublishedContent); //if (!implements) // return; disco.SetStaticMixinMethod(classSymbol.Name, methodSymbol.Name, returnType.Name, paramType.Name); }
private static void ParseAssemblySymbols(ParseResult disco, ISymbol symbol) { foreach (var attrData in symbol.GetAttributes()) { var attrClassSymbol = attrData.AttributeClass; // handle errors if (attrClassSymbol is IErrorTypeSymbol) continue; if (attrData.AttributeConstructor == null) continue; var attrClassName = SymbolDisplay.ToDisplayString(attrClassSymbol); switch (attrClassName) { case "Umbraco.ModelsBuilder.IgnoreContentTypeAttribute": var contentAliasToIgnore = (string)attrData.ConstructorArguments[0].Value; // see notes in IgnoreContentTypeAttribute //var ignoreContent = (bool)attrData.ConstructorArguments[1].Value; //var ignoreMixin = (bool)attrData.ConstructorArguments[1].Value; //var ignoreMixinProperties = (bool)attrData.ConstructorArguments[1].Value; disco.SetIgnoredContent(contentAliasToIgnore /*, ignoreContent, ignoreMixin, ignoreMixinProperties*/); break; case "Umbraco.ModelsBuilder.RenameContentTypeAttribute": var contentAliasToRename = (string) attrData.ConstructorArguments[0].Value; var contentRenamed = (string)attrData.ConstructorArguments[1].Value; disco.SetRenamedContent(contentAliasToRename, contentRenamed, false); break; case "Umbraco.ModelsBuilder.ModelsBaseClassAttribute": var modelsBaseClass = (INamedTypeSymbol) attrData.ConstructorArguments[0].Value; if (modelsBaseClass is IErrorTypeSymbol) throw new Exception(string.Format("Invalid base class type \"{0}\".", modelsBaseClass.Name)); disco.SetModelsBaseClassName(SymbolDisplay.ToDisplayString(modelsBaseClass)); break; case "Umbraco.ModelsBuilder.ModelsNamespaceAttribute": var modelsNamespace= (string) attrData.ConstructorArguments[0].Value; disco.SetModelsNamespace(modelsNamespace); break; case "Umbraco.ModelsBuilder.ModelsUsingAttribute": var usingNamespace = (string)attrData.ConstructorArguments[0].Value; disco.SetUsingNamespace(usingNamespace); break; } } }
private static void ParsePropertySymbols(ParseResult disco, ISymbol classSymbol, ISymbol symbol) { foreach (var attrData in symbol.GetAttributes()) { var attrClassSymbol = attrData.AttributeClass; // handle errors if (attrClassSymbol is IErrorTypeSymbol) continue; if (attrData.AttributeConstructor == null) continue; var attrClassName = SymbolDisplay.ToDisplayString(attrClassSymbol); switch (attrClassName) { case "Umbraco.ModelsBuilder.ImplementPropertyTypeAttribute": var propertyAliasToIgnore = (string)attrData.ConstructorArguments[0].Value; disco.SetIgnoredProperty(classSymbol.Name /*SymbolDisplay.ToDisplayString(classSymbol)*/, propertyAliasToIgnore); break; } } }
private static void ParseClassSymbols(ParseResult disco, ISymbol symbol) { foreach (var attrData in symbol.GetAttributes()) { var attrClassSymbol = attrData.AttributeClass; // handle errors if (attrClassSymbol is IErrorTypeSymbol) continue; if (attrData.AttributeConstructor == null) continue; var attrClassName = SymbolDisplay.ToDisplayString(attrClassSymbol); switch (attrClassName) { case "Umbraco.ModelsBuilder.IgnorePropertyTypeAttribute": var propertyAliasToIgnore = (string)attrData.ConstructorArguments[0].Value; disco.SetIgnoredProperty(symbol.Name /*SymbolDisplay.ToDisplayString(symbol)*/, propertyAliasToIgnore); break; case "Umbraco.ModelsBuilder.RenamePropertyTypeAttribute": var propertyAliasToRename = (string)attrData.ConstructorArguments[0].Value; var propertyRenamed = (string)attrData.ConstructorArguments[1].Value; disco.SetRenamedProperty(symbol.Name /*SymbolDisplay.ToDisplayString(symbol)*/, propertyAliasToRename, propertyRenamed); break; // that one causes all sorts of issues with references to Umbraco.Core in Roslyn //case "Umbraco.Core.Models.PublishedContent.PublishedContentModelAttribute": // var contentAliasToRename = (string)attrData.ConstructorArguments[0].Value; // disco.SetRenamedContent(contentAliasToRename, symbol.Name /*SymbolDisplay.ToDisplayString(symbol)*/); // break; case "Umbraco.ModelsBuilder.ImplementContentTypeAttribute": var contentAliasToRename = (string)attrData.ConstructorArguments[0].Value; disco.SetRenamedContent(contentAliasToRename, symbol.Name, true /*SymbolDisplay.ToDisplayString(symbol)*/); break; } } }
/// <summary> /// Initializes a new instance of the <see cref="TextBuilder"/> class with a list of models to generate, /// the result of code parsing, and a models namespace. /// </summary> /// <param name="typeModels">The list of models to generate.</param> /// <param name="parseResult">The result of code parsing.</param> /// <param name="modelsNamespace">The models namespace.</param> public TextBuilder(IList<TypeModel> typeModels, ParseResult parseResult, string modelsNamespace) : base(typeModels, parseResult, modelsNamespace) { }