protected PropertyGeneratorBase(T type, Property property, ISymbolMap symbols, INamespaceSet namespaces) { Type = type ?? throw new ArgumentNullException(nameof(type)); Property = property ?? throw new ArgumentNullException(nameof(property)); Symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); Namespaces = namespaces ?? throw new ArgumentNullException(nameof(namespaces)); }
public bool IsVaild(ISymbolMap symbol, out string message) { DebugSymbolMap debug = symbol as DebugSymbolMap; GItem[] vs = m_items; Range[] map = m_nonterminals; int x = vs.Length; string result = string.Empty; int errorcnt = 1; while (--x >= 0) { GItem current = vs[x]; ExpressInt expression = current.express; int len = expression.Length; while (--len >= 0) { int now = expression[len]; if (!now.IsTerminal() && map[now.ToIndex()] == default) { result += $"[{errorcnt++}] Invalid Non-Terminal: " + (debug?.Get(now) ?? $"<{now}>") + Environment.NewLine; } } } message = result; return(result.Length == 0); }
protected MethodGeneratorBase(T type, Method method, ISymbolMap symbols, INamespaceSet namespaces) { Type = type ?? throw new ArgumentNullException(nameof(type)); Method = method ?? throw new ArgumentNullException(nameof(method)); Symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); Namespaces = namespaces ?? throw new ArgumentNullException(nameof(namespaces)); }
public static void MapTypeName(this ISymbolMap symbols, string fullyQualifiedName, string frameworkName, TypeKind kind) { var proxyName = $"{frameworkName}Proxy"; switch (kind) { case TypeKind.Interface: var defaultName = frameworkName; symbols .GetInterfaceProxyName(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(proxyName); symbols .GetInterfaceDefaultName(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(defaultName); symbols .GetInterfaceProxyNameSyntaxToken(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseToken(proxyName)); symbols .GetInterfaceDefaultNameSyntaxToken(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseToken(defaultName)); symbols .GetInterfaceProxyNameSyntax(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseName(proxyName)); symbols .GetInterfaceDefaultNameSyntax(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseName(defaultName)); frameworkName = $"I{frameworkName}"; break; case TypeKind.Class: symbols .GetAbstractClassProxyName(Arg.Is <ClassType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(proxyName); break; } symbols .GetName(Arg.Is <Type>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(frameworkName); symbols .GetName(Arg.Is <string>(fqn => fqn == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(frameworkName); symbols .GetNameSyntaxToken(Arg.Is <Type>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseToken(frameworkName)); symbols .GetNameSyntaxToken(Arg.Is <string>(fqn => fqn == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseToken(frameworkName)); symbols .GetNameSyntax(Arg.Is <Type>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseName(frameworkName)); symbols .GetNameSyntax(Arg.Is <string>(fqn => fqn == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseName(frameworkName)); symbols .GetTypeSyntax(Arg.Is <TypeReference>(t => t.FullyQualifiedName == fullyQualifiedName), false) .Returns(SF.ParseTypeName(frameworkName)); }
public void Generate(string jsiiFile, string tarballPath, ISymbolMap symbols = null) { jsiiFile = jsiiFile ?? throw new ArgumentNullException(nameof(jsiiFile)); symbols = symbols ?? new SymbolMap(); string assemblyJson = _fileSystem.File.ReadAllText(jsiiFile); Assembly assembly = JsonConvert.DeserializeObject <Assembly>(assemblyJson); symbols.Add(assembly); LoadDependencies(assembly, Path.GetDirectoryName(jsiiFile)); string packageOutputRoot = Path.Combine(_outputRoot, assembly.GetNativeName()); if (_fileSystem.Directory.Exists(packageOutputRoot)) { _fileSystem.Directory.Delete(packageOutputRoot, true); } _fileSystem.Directory.CreateDirectory(packageOutputRoot); // On Windows, the full destination path including the filename is required. _fileSystem.File.Copy(tarballPath, Path.Combine(packageOutputRoot, Path.GetFileName(tarballPath))); _fileSystem.File.Copy(jsiiFile, Path.Combine(packageOutputRoot, Path.GetFileName(jsiiFile))); Save(packageOutputRoot, symbols, assembly, new FileInfo(tarballPath).Name, new FileInfo(jsiiFile).Name); void LoadDependencies(DependencyRoot dependencyRoot, string packageDirectory) { if (dependencyRoot.Dependencies == null) { return; } foreach (KeyValuePair <string, PackageVersion> entry in dependencyRoot.Dependencies) { string depRoot = ResolvePackage(entry.Key, packageDirectory); string depFile = Path.Combine(depRoot, ".jsii"); string depJson = _fileSystem.File.ReadAllText(depFile); Assembly depAssembly = JsonConvert.DeserializeObject <Assembly>(depJson); symbols.Add(depAssembly); LoadDependencies(depAssembly, depRoot); } string ResolvePackage(string packageName, string directory) { if (string.IsNullOrEmpty(directory)) { throw new FileNotFoundException($"Could not resolve package named {packageName}"); } string candidate = Path.Combine(directory, "node_modules", packageName); if (_fileSystem.Directory.Exists(candidate)) { return(candidate); } return(ResolvePackage(packageName, Path.GetDirectoryName(directory))); } } }
public AbstractClassProxyGenerator(string package, ClassType type, ISymbolMap symbols, INamespaceSet namespaces = null) : base(package, type, symbols, namespaces) { if (!type.IsAbstract) { throw new ArgumentException("Class type must be abstract.", nameof(type)); } }
protected TypeGeneratorBase(string package, T type, ISymbolMap symbols, INamespaceSet namespaces) { Package = package ?? throw new ArgumentNullException(nameof(package)); Type = type ?? throw new ArgumentNullException(nameof(type)); Symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); NameSyntax namespaceSyntax = Symbols.GetNamespaceSyntax(Type); Namespaces = namespaces ?? new NamespaceSet(Symbols, namespaceSyntax); }
public NamespaceSet(ISymbolMap symbols, NameSyntax currentNamespace) { _symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); _currentNamespace = currentNamespace ?? throw new ArgumentNullException(nameof(currentNamespace)); _referencedNamespaces = new HashSet <NameSyntax> ( new[] { SF.ParseName("Amazon.JSII.Runtime.Deputy") }, new DelegateComparer <NameSyntax, string>(nameSyntax => nameSyntax.ToString()) ); }
public static void MapTypeToNamespace(this ISymbolMap symbols, string fullyQualifiedName, string frameworkNamespace) { symbols .GetNamespace(Arg.Is <string>(n => n == fullyQualifiedName)) .Returns(frameworkNamespace); symbols .GetNamespaceSyntaxToken(Arg.Is <string>(n => n == fullyQualifiedName)) .Returns(SF.ParseToken(frameworkNamespace)); symbols .GetNamespaceSyntax(Arg.Is <string>(n => n == fullyQualifiedName)) .Returns(SF.ParseName(frameworkNamespace)); }
public static void MapNamespace(this ISymbolMap symbols, string jsiiNamespace, string frameworkNamespace) { symbols .GetNamespace(Arg.Is <Type>(t => t.QualifiedNamespace == jsiiNamespace)) .Returns(frameworkNamespace); symbols .GetNamespaceSyntaxToken(Arg.Is <Type>(t => t.QualifiedNamespace == jsiiNamespace)) .Returns(SF.ParseToken(frameworkNamespace)); symbols .GetNamespaceSyntax(Arg.Is <Type>(t => t.QualifiedNamespace == jsiiNamespace)) .Returns(SF.ParseName(frameworkNamespace)); }
public static void MapTypeName(this ISymbolMap symbols, string fullyQualifiedName, string frameworkName, TypeKind kind) { if (kind == TypeKind.Interface) { string proxyName = $"{frameworkName}Proxy"; string defaultName = frameworkName; symbols .GetInterfaceProxyName(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(proxyName); symbols .GetInterfaceDefaultName(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(defaultName); symbols .GetInterfaceProxyNameSyntaxToken(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseToken(proxyName)); symbols .GetInterfaceDefaultNameSyntaxToken(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseToken(defaultName)); symbols .GetInterfaceProxyNameSyntax(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseName(proxyName)); symbols .GetInterfaceDefaultNameSyntax(Arg.Is <InterfaceType>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseName(defaultName)); frameworkName = $"I{frameworkName}"; } symbols .GetName(Arg.Is <Type>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(frameworkName); symbols .GetName(Arg.Is <string>(fqn => fqn == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(frameworkName); symbols .GetNameSyntaxToken(Arg.Is <Type>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseToken(frameworkName)); symbols .GetNameSyntaxToken(Arg.Is <string>(fqn => fqn == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseToken(frameworkName)); symbols .GetNameSyntax(Arg.Is <Type>(t => t.FullyQualifiedName == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseName(frameworkName)); symbols .GetNameSyntax(Arg.Is <string>(fqn => fqn == fullyQualifiedName), disambiguate: Arg.Any <bool>()) .Returns(SF.ParseName(frameworkName)); symbols .GetTypeSyntax(Arg.Is <TypeReference>(t => t.FullyQualifiedName == fullyQualifiedName)) .Returns(SF.ParseTypeName(frameworkName)); }
public static void MapPropertyName(this ISymbolMap symbols, string ownerFullyQualifiedName, string jsiiName, string frameworkName) { symbols.GetName( Arg.Is <Type>(t => t.FullyQualifiedName == ownerFullyQualifiedName), Arg.Is <Property>(p => p.Name == jsiiName) ).Returns(frameworkName); symbols.GetNameSyntaxToken( Arg.Is <Type>(t => t.FullyQualifiedName == ownerFullyQualifiedName), Arg.Is <Property>(p => p.Name == jsiiName) ).Returns(SF.ParseToken(frameworkName)); symbols.GetNameSyntax( Arg.Is <Type>(t => t.FullyQualifiedName == ownerFullyQualifiedName), Arg.Is <Property>(p => p.Name == jsiiName) ).Returns(SF.ParseName(frameworkName)); }
public static void MapAssemblyName(this ISymbolMap symbols, string jsiiName, string frameworkName) { symbols .GetName(Arg.Is <Assembly>(a => a.Name == jsiiName)) .Returns(frameworkName); symbols .GetNameSyntaxToken(Arg.Is <Assembly>(a => a.Name == jsiiName)) .Returns(SF.ParseToken(frameworkName)); symbols .GetNameSyntax(Arg.Is <Assembly>(a => a.Name == jsiiName)) .Returns(SF.ParseName(frameworkName)); symbols .GetAssemblyName(Arg.Is <string>(n => n == jsiiName)) .Returns(frameworkName); }
public static bool AnyAncestor(this ClassType classType, ISymbolMap symbols, Func <ClassType, bool> predicate) { var current = classType.Base; while (current != null) { ClassType currentType = (ClassType)symbols.GetTypeFromFullyQualifiedName(current); if (predicate(currentType)) { return(true); } current = currentType.Base; } return(false); }
static IEnumerable <T> GetAllCore <T>(this InterfaceType @interface, ISymbolMap symbols, Func <InterfaceType, IEnumerable <T> > selector) { foreach (T member in selector(@interface) ?? Enumerable.Empty <T>()) { yield return(member); } if (@interface.Interfaces != null) { var baseMembers = @interface.Interfaces .Select(r => symbols.GetTypeFromFullyQualifiedName(r) as InterfaceType) .SelectMany(i => GetAllCore(i, symbols, selector)); foreach (T member in baseMembers) { yield return(member); } } }
public static void MapTypeToPackage(this ISymbolMap symbols, string fullyQualifiedName, string package) { symbols .GetPackage(Arg.Is <Type>(t => t.FullyQualifiedName == fullyQualifiedName)) .Returns(package); symbols .GetPackage(Arg.Is <string>(n => n == fullyQualifiedName)) .Returns(package); symbols .GetPackageSyntaxToken(Arg.Is <Type>(t => t.FullyQualifiedName == fullyQualifiedName)) .Returns(SF.ParseToken(package)); symbols .GetPackageSyntaxToken(Arg.Is <string>(n => n == fullyQualifiedName)) .Returns(SF.ParseToken(package)); symbols .GetPackageSyntax(Arg.Is <Type>(t => t.FullyQualifiedName == fullyQualifiedName)) .Returns(SF.ParseName(package)); symbols .GetPackageSyntax(Arg.Is <string>(n => n == fullyQualifiedName)) .Returns(SF.ParseName(package)); }
public InterfaceProxyMethodGenerator(InterfaceType type, Method method, ISymbolMap symbols, INamespaceSet namespaces) : base(type, method, symbols, namespaces) { if (!method.IsAbstract) { throw new ArgumentException("Interface methods must be abstract", nameof(method)); } if (method.IsProtected) { throw new ArgumentException("Protected methods are not allowed on interfaces", nameof(method)); } if (method.IsStatic) { throw new ArgumentException( $"Method {type.Name}.{method.Name} is marked as static, but interfaces must not contain static members.", nameof(method) ); } }
public InterfacePropertyGenerator(InterfaceType type, Property property, ISymbolMap symbols, INamespaceSet namespaces) : base(type, property, symbols, namespaces) { if (property.IsAbstract == true) { throw new ArgumentException("Abstract properties are not allowed on interfaces", nameof(property)); } if (property.IsProtected == true) { throw new ArgumentException("Protected properties are not allowed on interfaces", nameof(property)); } if (property.IsStatic()) { throw new ArgumentException( $"Property {type.Name}.{property.Name} is marked as static, but interfaces must not contain static members.", nameof(property) ); } }
void Save(string packageOutputRoot, ISymbolMap symbols, Assembly assembly, string tarballFileName, string jsiiFileName) { if (assembly.Docs != null) { // TODO: Use Microsoft.Extensions.Logging instead of Console.Error. Console.Error.WriteLine($"Warning: Ignoring documentation comment on assembly {assembly.Name}. Assembly-level documentation comments are not supported for .NET"); } SaveProjectFile(); SaveAssemblyInfo(assembly.Name, assembly.Version, tarballFileName); SaveDependencyAnchorFile(); foreach (Type type in assembly.Types?.Values ?? Enumerable.Empty <Type>()) { SaveType(type); } void SaveProjectFile() { XElement project = new XElement("Project", new XAttribute("Sdk", "Microsoft.NET.Sdk"), new XElement("PropertyGroup", assembly.GetMsBuildProperties()), new XElement("ItemGroup", new XElement("EmbeddedResource", new XAttribute("Include", tarballFileName) ) ), new XElement("ItemGroup", new XElement("PackageReference", new XAttribute("Include", "Amazon.JSII.Runtime"), new XAttribute("Version", JsiiVersion.Version) ), GetDependencies() .Distinct() .Select(d => new { Package = symbols.GetAssemblyName(d.Key), Version = d.Value.GetDecoratedVersion() }) .Select(d => new XElement("PackageReference", new XAttribute("Include", d.Package), new XAttribute("Version", d.Version) ) ) ) ); if (!_fileSystem.Directory.Exists(packageOutputRoot)) { _fileSystem.Directory.CreateDirectory(packageOutputRoot); } // Save to StringBuilder instead of directly to path, so that we can // redirect the output through the filesystem shim. Project files are // small, so this shouldn't be a memory hog. StringBuilder builder = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings { // Visual Studio omits the XML declaration when creating project files, so we do too. OmitXmlDeclaration = true, // Visual Studio indents project files (they are often edited by hand), so we do too. Indent = true, }; using (XmlWriter writer = XmlWriter.Create(builder, settings)) { project.Save(writer); } string csProjPath = Path.Combine(packageOutputRoot, $"{assembly.GetNativePackageId()}.csproj"); _fileSystem.File.WriteAllText(csProjPath, builder.ToString()); IEnumerable <KeyValuePair <string, PackageVersion> > GetDependencies() { foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(assembly)) { yield return(dependency); } IEnumerable <KeyValuePair <string, PackageVersion> > GetDependenciesCore(DependencyRoot root) { if (root.Dependencies == null) { yield break; } foreach (var kvp in root.Dependencies) { yield return(kvp); foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(kvp.Value)) { yield return(dependency); } } } } } void SaveDependencyAnchorFile() { string anchorNamespace = $"{assembly.GetNativeNamespace()}.Internal.DependencyResolution"; var syntaxTree = SF.SyntaxTree( SF.CompilationUnit( SF.List <ExternAliasDirectiveSyntax>(), SF.List <UsingDirectiveSyntax>(), SF.List <AttributeListSyntax>(), SF.List <MemberDeclarationSyntax>(new[] { SF.NamespaceDeclaration( SF.IdentifierName(anchorNamespace), SF.List <ExternAliasDirectiveSyntax>(), SF.List <UsingDirectiveSyntax>(), SF.List(new MemberDeclarationSyntax[] { GenerateDependencyAnchor() }) ) }) ).NormalizeWhitespace(elasticTrivia: true) ); string directory = GetNamespaceDirectory(packageOutputRoot, @anchorNamespace); SaveSyntaxTree(directory, "Anchor.cs", syntaxTree); ClassDeclarationSyntax GenerateDependencyAnchor() { return(SF.ClassDeclaration( SF.List <AttributeListSyntax>(), SF.TokenList(SF.Token(SyntaxKind.PublicKeyword)), SF.Identifier("Anchor"), null, null, SF.List <TypeParameterConstraintClauseSyntax>(), SF.List(new MemberDeclarationSyntax[] { SF.ConstructorDeclaration( SF.List <AttributeListSyntax>(), SF.TokenList(SF.Token(SyntaxKind.PublicKeyword)), SF.Identifier("Anchor"), SF.ParameterList(SF.SeparatedList <ParameterSyntax>()), null, SF.Block(SF.List(GenerateAnchorReferences())), null ) }) )); IEnumerable <StatementSyntax> GenerateAnchorReferences() { return(assembly.Dependencies?.Keys .Select(k => assembly.GetNativeNamespace(k)) .Select(n => $"{n}.Internal.DependencyResolution.Anchor") .Select(t => SF.ExpressionStatement(SF.ObjectCreationExpression( SF.Token(SyntaxKind.NewKeyword), SF.ParseTypeName(t), SF.ArgumentList(SF.SeparatedList <ArgumentSyntax>()), null ))) ?? Enumerable.Empty <StatementSyntax>()); } } } void SaveAssemblyInfo(string name, string version, string tarball) { SyntaxTree assemblyInfo = SF.SyntaxTree( SF.CompilationUnit( SF.List <ExternAliasDirectiveSyntax>(), SF.List(new[] { SF.UsingDirective(SF.ParseName("Amazon.JSII.Runtime.Deputy")) }), SF.List(new[] { SF.AttributeList( SF.AttributeTargetSpecifier( SF.Identifier("assembly"), SF.Token(SyntaxKind.ColonToken) ), SF.SeparatedList(new[] { SF.Attribute( SF.ParseName("JsiiAssembly"), SF.ParseAttributeArgumentList($"({SF.Literal(name)}, {SF.Literal(version)}, {SF.Literal(tarball)})") ) }) ) }), SF.List <MemberDeclarationSyntax>() ).NormalizeWhitespace(elasticTrivia: true) ); string assemblyInfoPath = Path.Combine(packageOutputRoot, "AssemblyInfo.cs"); _fileSystem.File.WriteAllText(assemblyInfoPath, assemblyInfo.ToString()); } void SaveType(Type type) { string @namespace = symbols.GetNamespace(type); string directory = GetNamespaceDirectory(packageOutputRoot, @namespace); switch (type.Kind) { case TypeKind.Class: { var classType = (ClassType)type; if (classType.IsAbstract) { SaveTypeFile($"{symbols.GetAbstractClassProxyName(classType)}.cs", new AbstractClassProxyGenerator(assembly.Name, classType, symbols).CreateSyntaxTree()); } SaveTypeFile($"{symbols.GetName(type)}.cs", new ClassGenerator(assembly.Name, classType, symbols).CreateSyntaxTree()); return; } case TypeKind.Enum: { SaveTypeFile($"{symbols.GetName(type)}.cs", new EnumGenerator(assembly.Name, (EnumType)type, symbols).CreateSyntaxTree()); return; } case TypeKind.Interface: { InterfaceType interfaceType = (InterfaceType)type; SaveTypeFile($"{symbols.GetName(interfaceType)}.cs", new InterfaceGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); SaveTypeFile($"{symbols.GetInterfaceProxyName(interfaceType)}.cs", new InterfaceProxyGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); if (interfaceType.IsDataType) { SaveTypeFile($"{symbols.GetInterfaceDefaultName(interfaceType)}.cs", new InterfaceDefaultGenerator(assembly.Name, interfaceType, symbols) .CreateSyntaxTree()); } return; } default: { throw new ArgumentException($"Unkown type kind: {type.Kind}", nameof(type)); } } void SaveTypeFile(string filename, SyntaxTree syntaxTree) { SaveSyntaxTree(directory, filename, syntaxTree); } } void SaveSyntaxTree(string directory, string filename, SyntaxTree syntaxTree) { if (!_fileSystem.Directory.Exists(directory)) { _fileSystem.Directory.CreateDirectory(directory); } _fileSystem.File.WriteAllText( Path.Combine(directory, filename), syntaxTree.ToString() ); } }
public static IEnumerable <Property> GetAllProperties(this InterfaceType @interface, ISymbolMap symbols) { @interface = @interface ?? throw new ArgumentNullException(nameof(@interface)); symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); return(GetAllCore(@interface, symbols, i => i.Properties)); }
public static void MapFullyQualifiedNameToType(this ISymbolMap symbols, string fullyQualifiedName, Type type) { symbols .GetTypeFromFullyQualifiedName(Arg.Is <string>(n => n == fullyQualifiedName)) .Returns(type); }
public InterfaceGenerator(string package, InterfaceType type, ISymbolMap symbols, INamespaceSet namespaces = null) : base(package, type, symbols, namespaces) { }
public static ParameterListSyntax GetParameterListSyntax(this Method method, INamespaceSet namespaces, ISymbolMap symbols) { method = method ?? throw new ArgumentNullException(nameof(method)); namespaces = namespaces ?? throw new ArgumentNullException(nameof(namespaces)); symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); return(SF.ParameterList(SF.SeparatedList(GetParameters()))); IEnumerable <ParameterSyntax> GetParameters() { if (method.Parameters == null) { yield break; } foreach (Parameter parameter in method.Parameters) { namespaces.Add(parameter.Type); yield return(SF.Parameter( SF.List <AttributeListSyntax>(), SF.TokenList(), symbols.GetTypeSyntax(parameter.Type), symbols.GetNameSyntaxToken(parameter), null )); } } }
public ClassPropertyGenerator(ClassType type, Property property, ISymbolMap symbols, INamespaceSet namespaces) : base(type, property, symbols, namespaces) { }
public ClassMethodGenerator(ClassType type, Method method, ISymbolMap symbols, INamespaceSet namespaces) : base(type, method, symbols, namespaces) { }
public EnumGenerator(string package, EnumType type, ISymbolMap symbols, INamespaceSet namespaces = null) : base(package, type, symbols, namespaces) { }
public static void MapParameterName(this ISymbolMap symbols, string jsiiName, string frameworkName) { symbols.GetName(Arg.Is <Parameter>(t => t.Name == jsiiName)).Returns(frameworkName); symbols.GetNameSyntaxToken(Arg.Is <Parameter>(t => t.Name == jsiiName)).Returns(SF.ParseToken(frameworkName)); symbols.GetNameSyntax(Arg.Is <Parameter>(t => t.Name == jsiiName)).Returns(SF.ParseName(frameworkName)); }
protected TypeProxyGeneratorBase(string package, T type, ISymbolMap symbols, INamespaceSet namespaces) : base(package, type, symbols, namespaces) { }
void Save(string packageOutputRoot, ISymbolMap symbols, Assembly assembly, string tarballFileName, string jsiiFileName) { if (assembly.Docs != null) { // TODO: Use Microsoft.Extensions.Logging instead of Console.Error. Console.Error.WriteLine("Warning: Ignoring documentation comment on assembly ${assembly.Name}. Assembly-level documentation comments are not supported for .NET"); } SaveProjectFile(); SaveAssemblyInfo(assembly.Name, assembly.Version, tarballFileName); foreach (Type type in assembly.Types?.Values ?? Enumerable.Empty <Type>()) { SaveType(type); } void SaveProjectFile() { XElement project = new XElement("Project", new XAttribute("Sdk", "Microsoft.NET.Sdk"), new XElement("PropertyGroup", new XElement("TargetFramework", "netstandard2.0"), new XElement("GeneratePackageOnBuild", true), new XElement("Authors", _authors), new XElement("Company", _company), new XElement("PackageVersion", assembly.Version) ), new XElement("ItemGroup", new XElement("EmbeddedResource", new XAttribute("Include", tarballFileName) ) ), new XElement("ItemGroup", new XElement("PackageReference", new XAttribute("Include", "Amazon.JSII.Runtime"), new XAttribute("Version", JsiiVersion.Version) ), GetDependencies() .Distinct() .Select(d => new { Package = symbols.GetAssemblyName(d.Key), Version = d.Value.Version }) .Select(d => new XElement("PackageReference", new XAttribute("Include", d.Package), new XAttribute("Version", d.Version) ) ) ) ); if (!_fileSystem.Directory.Exists(packageOutputRoot)) { _fileSystem.Directory.CreateDirectory(packageOutputRoot); } // Save to StringBuilder instead of directly to path, so that we can // redirect the output through the filesystem shim. Project files are // small, so this shouldn't be a memory hog. StringBuilder builder = new StringBuilder(); XmlWriterSettings settings = new XmlWriterSettings { // Visual Studio omits the XML declaration when creating project files, so we do too. OmitXmlDeclaration = true, // Visual Studio indents project files (they are often edited by hand), so we do too. Indent = true, }; using (XmlWriter writer = XmlWriter.Create(builder, settings)) { project.Save(writer); } string csProjPath = Path.Combine(packageOutputRoot, $"{assembly.GetNativeName()}.csproj"); _fileSystem.File.WriteAllText(csProjPath, builder.ToString()); IEnumerable <KeyValuePair <string, PackageVersion> > GetDependencies() { foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(assembly)) { yield return(dependency); } IEnumerable <KeyValuePair <string, PackageVersion> > GetDependenciesCore(DependencyRoot root) { if (root.Dependencies == null) { yield break; } foreach (var kvp in root.Dependencies) { yield return(kvp); foreach (KeyValuePair <string, PackageVersion> dependency in GetDependenciesCore(kvp.Value)) { yield return(dependency); } } } } } void SaveAssemblyInfo(string name, string version, string tarball) { SyntaxTree assemblyInfo = SF.SyntaxTree( SF.CompilationUnit( SF.List <ExternAliasDirectiveSyntax>(), SF.List(new[] { SF.UsingDirective(SF.ParseName("Amazon.JSII.Runtime.Deputy")) }), SF.List(new[] { SF.AttributeList( SF.AttributeTargetSpecifier( SF.Identifier("assembly"), SF.Token(SyntaxKind.ColonToken) ), SF.SeparatedList(new[] { SF.Attribute( SF.ParseName("JsiiAssembly"), SF.ParseAttributeArgumentList($"({SF.Literal(name)}, {SF.Literal(version)}, {SF.Literal(tarball)})") ) }) ) }), SF.List <MemberDeclarationSyntax>() ).NormalizeWhitespace(elasticTrivia: true) ); string assemblyInfoPath = Path.Combine(packageOutputRoot, "AssemblyInfo.cs"); _fileSystem.File.WriteAllText(assemblyInfoPath, assemblyInfo.ToString()); } void SaveType(Type type) { string packageName = Path.GetFileName(packageOutputRoot); string @namespace = symbols.GetNamespace(type); if (@namespace.StartsWith(packageName)) { @namespace = @namespace.Substring(packageName.Length).TrimStart('.'); } string directory = Path.Combine(packageOutputRoot, Path.Combine(@namespace.Split('.'))); switch (type.Kind) { case TypeKind.Class: SaveTypeFile($"{symbols.GetName(type)}.cs", new ClassGenerator(assembly.Name, (ClassType)type, symbols).CreateSyntaxTree()); return; case TypeKind.Enum: SaveTypeFile($"{symbols.GetName(type)}.cs", new EnumGenerator(assembly.Name, (EnumType)type, symbols).CreateSyntaxTree()); return; case TypeKind.Interface: InterfaceType interfaceType = (InterfaceType)type; SaveTypeFile($"{symbols.GetName(interfaceType)}.cs", new InterfaceGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); SaveTypeFile($"{symbols.GetInterfaceProxyName(interfaceType)}.cs", new InterfaceProxyGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); if (interfaceType.IsDataType == true) { SaveTypeFile($"{symbols.GetInterfaceDefaultName(interfaceType)}.cs", new InterfaceDefaultGenerator(assembly.Name, interfaceType, symbols).CreateSyntaxTree()); } return; default: throw new ArgumentException($"Unkown type kind: {type.Kind}", nameof(type)); } void SaveTypeFile(string filename, SyntaxTree syntaxTree) { if (!_fileSystem.Directory.Exists(directory)) { _fileSystem.Directory.CreateDirectory(directory); } _fileSystem.File.WriteAllText( Path.Combine(directory, filename), syntaxTree.ToString() ); } } }
public MethodDocCommentGenerator(Callable documentable, ISymbolMap symbols) : base(documentable) { _symbols = symbols ?? throw new ArgumentNullException(nameof(symbols)); }