public string GenerateFrom(string workingDirectory, string assetName, DOMDocument document) { m_File = new CSFile(document.@namespace) .AddWarningDisable(414) .AddInclude("System.ComponentModel") .AddInclude("UnityEngine") .AddInclude("UnityEditor.Experimental.VisualElements") .AddInclude("UnityEditor"); m_Class = new CSClass(Scope.Internal, assetName, CSClass.Modifier.Partial) .AddParent("EditorWindow"); m_File.AddClass(m_Class); m_AwakeMethod = new CSMethod(Scope.Private, "void", "Awake"); m_Class.AddMethod(m_AwakeMethod); m_OnDestroyMethod = new CSMethod(Scope.Private, "void", "OnDestroy"); m_Class.AddMethod(m_OnDestroyMethod); m_OnVMPropertyChanged = new CSMethod(Scope.Private, "void", "VmOnPropertyChanged") .AddArgument("object", "sender") .AddArgument("PropertyChangedEventArgs", "propertyChangedEventArgs") .AddBodyLine("Repaint();"); m_Class.AddMethod(m_OnVMPropertyChanged); VisitIn(document); VisitIn(document.usings); VisitIn(document.editorPrefsProperties); var builder = new StringBuilder(); m_File.GenerateIn(builder); return(builder.ToString()); }
public string GenerateFrom(string workingDirectory, string assetName, DOMDocument document) { m_Properties.Clear(); m_Usings.Clear(); m_Commands.Clear(); m_FileDependencies.Clear(); m_WorkingDirectory = workingDirectory; m_File = new CSFile(document.@namespace) .AddWarningDisable(414) .AddInclude("UnityEditor.Experimental.VisualElements"); m_Class = new CSClass(Scope.Internal, assetName, CSClass.Modifier.Partial) .AddParent("IMGUIVisualContainer"); m_File.AddClass(m_Class); if (document.nodes != null) { for (int i = 0; i < document.nodes.Length; i++) { Visit(document.nodes[i]); } } VisitIn(document.stylesheet); VisitIn(document.root); Build(); var builder = new StringBuilder(); m_File.GenerateIn(builder); return(builder.ToString()); }
public string GenerateFrom(string workingdir, string assetName, DOMDocument document) { m_File = new CSFile(document.@namespace); m_Class = new CSClass(Scope.Internal, assetName, CSClass.Modifier.Partial); m_File .AddClass(m_Class) .AddInclude("UnityEditor.Experimental.ViewModel") .AddWarningDisable(414); m_Class.AddParent("SerializedViewModelBase"); m_PropertyClass = new CSClass(Scope.Internal, "Properties", CSClass.Modifier.Static); m_Class.AddClass(m_PropertyClass); if (document.members != null) { for (int i = 0; i < document.members.Length; i++) { if (document.members[i] is DOMProperty) { RegisterPropertyGetterDependencies((DOMProperty)document.members[i]); } } for (int i = 0; i < document.members.Length; i++) { Visit(document.members[i]); } } var builder = new StringBuilder(); m_File.GenerateIn(builder); return(builder.ToString()); }
/// <summary> /// this will return a SortedList, the key is the interface name, /// and the value is the class with the full namespace that implements that interface /// </summary> /// <param name="ACSFiles"></param> /// <returns></returns> private SortedList GetInterfaceNamesFromImplementation(List <CSParser> ACSFiles) { SortedList Result = new SortedList(); foreach (CSParser CSFile in ACSFiles) { foreach (TypeDeclaration t in CSFile.GetClasses()) { string FullClassNameWithNamespace = CSFile.GetFullClassNameWithNamespace(t); if (FullClassNameWithNamespace.Contains("Connector")) { foreach (ICSharpCode.NRefactory.Ast.TypeReference ti in t.BaseTypes) { if (ti.Type.StartsWith("I")) { Result.Add(ti.Type, CSFile.GetFullClassNameWithNamespace(t)); } } } } } return(Result); }
public static void TestAndExecuteNoDevice(string swiftCode, CodeElementCollection <ICodeElement> callingCode, string expectedOutput, string testName = null, PlatformName platform = PlatformName.None, UnicodeMapper unicodeMapper = null) { SetInvokingTestNameIfUnset(ref testName, out string nameSpace); using (var provider = new DisposableTempDirectory()) { var compiler = Utils.CompileSwift(swiftCode, provider, nameSpace); var libName = $"lib{nameSpace}.dylib"; var tempDirectoryPath = Path.Combine(provider.DirectoryPath, "BuildDir"); Directory.CreateDirectory(tempDirectoryPath); File.Copy(Path.Combine(compiler.DirectoryPath, libName), Path.Combine(tempDirectoryPath, libName)); Utils.CompileToCSharp(provider, tempDirectoryPath, nameSpace, unicodeMapper: unicodeMapper); CSFile csFile = TestRunningCodeGenerator.GenerateTestEntry(callingCode, testName, nameSpace, platform); csFile.Namespaces.Add(CreateManagedConsoleRedirect()); CodeWriter.WriteToFile(Path.Combine(tempDirectoryPath, "NameNotImportant.cs"), csFile); var sourceFiles = Directory.GetFiles(tempDirectoryPath, "*.cs"); Compiler.CSCompile(tempDirectoryPath, sourceFiles, "NameNotImportant.exe", platform: platform); CopyTestReferencesTo(tempDirectoryPath, platform); var output = Execute(tempDirectoryPath, "NameNotImportant.exe", platform); Assert.AreEqual(expectedOutput, output); } }
public static CSFile GenerateTestEntry(CodeElementCollection <ICodeElement> callingCode, string testName, string nameSpace, PlatformName platform, CSClass otherClass = null) { var use = GetTestEntryPointUsings(nameSpace, platform); var ns = new CSNamespace(nameSpace); if (otherClass != null) { ns.Block.Add(otherClass); } var mainBody = new CSCodeBlock(callingCode); mainBody.Add(CaptureSwiftOutputPostlude(testName)); var main = new CSMethod(CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, (CSIdentifier)"Main", new CSParameterList(new CSParameter(CSSimpleType.CreateArray("string"), "args")), mainBody); var mainClass = new CSClass(CSVisibility.Public, "NameNotImportant", new CSMethod [] { main }); AddSupportingCode(mainClass, platform); ns.Block.Add(mainClass); return(CSFile.Create(use, ns)); }
public void Covert(Sqlite2CsConfig config) { CleanupOutput(config.outputPath); SQLiteConnectionStringBuilder sqlitestring = new SQLiteConnectionStringBuilder(); sqlitestring.DataSource = config.databaseFilePath; mSqliteConn = new SQLiteConnection(sqlitestring.ToString()); mSqliteConn.Open(); //mSqliteConn.StateChange += MSqliteConn_StateChange; Dictionary <string, string> tableInfoMap = GetTableInfo(config.databaseName, config.filterName); foreach (KeyValuePair <string, string> tableInfo in tableInfoMap) { CSFile csFile = ConvertTable(config.databaseName, tableInfo.Key, tableInfo.Value, config.CSdataClassImpledInterface); string filePath = config.outputPath + "/" + tableInfo.Key + ".cs"; if (File.Exists(filePath)) { Console.WriteLine("{0} already exists.", filePath); return; } using (StreamWriter sw = File.CreateText(filePath)) { sw.Write(csFile.GenerateFilsString()); sw.Close(); } } mSqliteConn.Close(); System.Windows.Forms.MessageBox.Show("写入完毕!!!"); }
string CompileWithInvokingCode(CSFile cs, CSLine invoker, string nameSpace) { CSNamespace ns = new CSNamespace(nameSpace); CSCodeBlock mainBody = CSCodeBlock.Create(invoker); CSMethod main = new CSMethod(CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, new CSIdentifier("Main"), new CSParameterList(new CSParameter(new CSSimpleType("string", true), "args")), mainBody); CSClass cl = new CSClass(CSVisibility.Public, "NameNotImportant", new CSMethod [] { main }); ns.Block.Add(cl); cs.Namespaces.Add(ns); using (DisposableTempFile csOut = new DisposableTempFile(null, null, "cs", true)) { CodeWriter.WriteToFile(csOut.Filename, cs); using (Stream csExeStm = Compiler.CompileUsing(null, XCodeCompiler.CSharpExe, csOut.Filename, $"-lib:{kSwiftRuntimeMacOutputDirectory} -r:{kSwiftRuntimeLibraryMac}")) { using (DisposableTempFile csExe = new DisposableTempFile(null, null, "exe", true)) { csExeStm.CopyTo(csExe.Stream); csExe.Stream.Close(); string output = Compiler.RunWithMono(csExe.Filename); return(output); } } } }
//Dictionary<string, string> GetTableInfo(string databaseName, string filterName) //{ // Dictionary<string, string> tableInfo = new Dictionary<string, string>(); // string sqlString = "select * from sqlite_master WHERE type = \"table\""; // using (SQLiteCommand cmd = mSqliteConn.CreateCommand()) // { // cmd.CommandText = sqlString; // SQLiteDataAdapter da = new SQLiteDataAdapter(cmd); // DataTable dt = new DataTable(); // da.Fill(dt); // DataColumn nameCol = dt.Columns["name"]; // foreach (DataRow row in dt.Rows) // { // string key = row[nameCol].ToString(); // if (filterName != "") // { // Regex regex = new Regex(@"^[" + filterName + "]"); // if (!regex.IsMatch(key)) // { // continue; // } // } // tableInfo.Add(key, null); // //System.Diagnostics.Trace.WriteLine("Unhandled sqlite type [" + + "]"); // } // } // return tableInfo; //} //string GetString(SQLiteDataReader reader, string ordinal) //{ // return reader.GetString(reader.GetOrdinal(ordinal)); //} ///// <summary> ///// Convsert specified xml file to cs file object ///// </summary> CSFile ConvertTable(string xmlFile, string[] impledInterface) { CSFile writer = new CSFile(); writer.name = Path.GetFileName(xmlFile); //read xml file writer.AddReferencedLib("System"); CSClass classObj = writer.AddCSClass("public", writer.name, impledInterface); using (XmlReader reader = XmlReader.Create("")) { XmlSchemaInference schema = new XmlSchemaInference(); XmlSchemaSet schemaSet = schema.InferSchema(reader); //schemaSet. } // string sqlString = string.Format("PRAGMA table_info([{0}]);", tableName); // using (SQLiteCommand cmd = mSqliteConn.CreateCommand()) // { // cmd.CommandText = sqlString; // //using // writer.AddReferencedLib("System"); // CSClass classObj = writer.AddCSClass("public", tableName, impledInterface); // SQLiteDataAdapter da = new SQLiteDataAdapter(cmd); // DataTable dt = new DataTable(); // da.Fill(dt); // DataColumn nameCol = dt.Columns["name"]; // DataColumn typeCol = dt.Columns["type"]; // CSParseFunc parseFunc = new CSParseFunc("public", tableName, "ReadData"); // CSVar dataForm = parseFunc.AddParam(string.Empty, "ASteinGameDataHolder", "dataForm"); // classObj.AddFuncDeclare(parseFunc); // foreach (DataRow row in dt.Rows) // { // CSField dataVar = classObj.AddVar("public", SqliteType2CsType(row[typeCol].ToString()), row[nameCol].ToString()); // CSFuncCall parseCall = new CSFuncCall(string.Empty, SqliteType2CsType(row[typeCol].ToString()), SqliteType2CsReadType(row[typeCol].ToString())); // parseCall.AddParam("string", row[nameCol].ToString()); // parseCall.targetObj = dataForm; // parseCall.returnVar = dataVar; // parseFunc.AddParseCall(parseCall); // } // } // //System.Diagnostics.Trace.WriteLine(writer.GenerateFilsString()); return(writer); }
public void ArcClassStruct() { string swiftCode = "public final class Foo {\npublic var _nm:String\npublic init(name:String) {\n_nm = name }\n" + "deinit {\nprint(_nm)\n}\n}\n" + "public struct Bar {\n public var a:Foo\n public init(f:Foo) {\n a = f\n}\n }\n" ; swiftCode += TestRunning.CreateSwiftConsoleRedirect(); using (TempDirectoryFilenameProvider provider = new TempDirectoryFilenameProvider(null, true)) { Utils.CompileSwift(swiftCode, provider); string libFileName = Path.Combine(provider.DirectoryPath, "libXython.dylib"); var errors = new ErrorHandling(); ModuleInventory.FromFile(libFileName, errors); Utils.CheckErrors(errors); Utils.CompileToCSharp(provider); CSUsingPackages use = new CSUsingPackages("System", "System.Runtime.InteropServices", "SwiftRuntimeLibrary"); CSNamespace ns = new CSNamespace("Xython"); CSFile csfile = CSFile.Create(use, ns); CSIdentifier inst = new CSIdentifier("inst"); CSLine newer = CSVariableDeclaration.VarLine((CSSimpleType)"Foo", inst, CSFunctionCall.Ctor("Foo", CSFunctionCall.Function("SwiftString.FromString", CSConstant.Val("nothing")))); CSIdentifier inst1 = new CSIdentifier("bar"); CSLine newer1 = CSVariableDeclaration.VarLine((CSSimpleType)"Bar", inst1, CSFunctionCall.Ctor("Bar", inst)); CSLine disposer = CSFunctionCall.FunctionCallLine(inst.Name + ".Dispose", false); CSLine disposer1 = CSFunctionCall.FunctionCallLine(inst1.Name + ".Dispose", false); CSCodeBlock mainBody = CSCodeBlock.Create(newer, newer1, disposer, disposer1); CSMethod main = new CSMethod(CSVisibility.Public, CSMethodKind.Static, CSSimpleType.Void, (CSIdentifier)"Main", new CSParameterList(new CSParameter(CSSimpleType.CreateArray("string"), "args")), mainBody); CSClass mainClass = new CSClass(CSVisibility.Public, "NameNotImportant", new CSMethod [] { main }); ns.Block.Add(mainClass); string csOutFilename = provider.ProvideFileFor(provider.UniqueName(null, "CSWrap", "cs")); var exeOutFilename = provider.UniquePath(null, "CSWrap", "exe"); CodeWriter.WriteToFile(csOutFilename, csfile); Compiler.CSCompile(provider.DirectoryPath, Directory.GetFiles(provider.DirectoryPath, "*.cs"), exeOutFilename); TestRunning.CopyTestReferencesTo(provider.DirectoryPath); string output = Compiler.RunWithMono(exeOutFilename, provider.DirectoryPath); Assert.AreEqual("nothing\n", output); } }
/// <summary> /// this will return a SortedList, the key is the class name, /// and the value is the type definition of the class that implements that interface; /// connectors are identified namespace ending with Connectors /// </summary> private static SortedList <string, TypeDeclaration> GetConnectors(List <CSParser> ACSFiles) { SortedList <string, TypeDeclaration> Result = new SortedList <string, TypeDeclaration>(); foreach (CSParser CSFile in ACSFiles) { foreach (TypeDeclaration t in CSFile.GetClasses()) { if (t.UserData.ToString().EndsWith("Connectors")) { if (t.Name.EndsWith("UIConnector")) { // deprecated. not implemented anymore. } // either a webconnector, or a partial class else { // web connectors don't derive from an interface, because the methods are static string ServerNamespace = t.UserData.ToString(); string key = ServerNamespace + "." + t.Name; if (Result.ContainsKey(key)) { // partial class foreach (INode child in t.Children) { Result[key].AddChild(child); } } else if (t.Name.EndsWith("UIConnector")) { // deprecated. not implemented anymore } else { Result.Add(key, t); } if (TLogging.DebugLevel > 1) { // TLogging.Log("adding new Connector " + key); } } } } } return(Result); }
public VXMLDOMElementVisitor(CSFile file, CSClass @class, CSMethod buildMethod) { m_File = file; m_Class = @class; SetHandler(this); m_BuildMethod = buildMethod; m_BindMethod = new CSMethod(Scope.Protected, "void", "Bind", CSMethod.Modifier.Override); m_Class.AddMethod(m_BindMethod); m_OnGUIMethod = new CSMethod(Scope.Public, "void", "OnGUI", CSMethod.Modifier.Override); m_WriteChildFormatStack = new Stack <string>(); PushAddChildMethod(string.Empty); }
public void Compile() { if (verbose) { NewClassCompiler.ReportCompileStatus(protocols, "ObjC protocols"); } if (!protocols.Any()) { return; } var use = new CSUsingPackages("System", "ObjCRuntime", "Foundation"); string nameSpace = typeMapper.MapModuleToNamespace(module.Name); var nm = new CSNamespace(nameSpace); var objCClasses = ObjCClasses(); foreach (var cl in objCClasses) { var csIface = BuildCSIface(cl, use); nm.Block.Add(csIface); } foreach (var proto in protocols) { if (proto.IsDeprecated || proto.IsUnavailable) { continue; } try { var iface = CompileProtocol(proto, use); nm.Block.Add(iface); } catch (Exception e) { errors.Add(e); } } var csfile = new CSFile(use, new CSNamespace [] { nm }); string csOutputFileName = $"{nameSpace}ObjCProtocol.cs"; NewClassCompiler.WriteCSFile(csOutputFileName, outputDirectory, csfile); var needsSwiftRuntimeLibrary = use.Elements.Any(elem => (elem as CSUsing).Contents.Contains("SwiftRuntimeLibrary")); YouCantBtouchThis(csOutputFileName, needsSwiftRuntimeLibrary); CleanUpExtraneousFiles(protocols, csOutputFileName); }
//遍历inputDir目录下所有csv文件,将文件生成cs文件 public static void GenerateDirectory(string inputDir, string outputName) { string[] fileList = Directory.GetFiles(inputDir, "*.csv", SearchOption.TopDirectoryOnly); CSFile csFile = new CSFile(); foreach (string fileName in fileList) { using (StreamReader sr = File.OpenText(fileName)) { string className = GetFileName(fileName); csFile.Add(className, GetText(className, sr.ReadToEnd())); } } using (StreamWriter sw = File.CreateText(outputName)) { sw.Write(csFile.Generate()); } }
/// <summary> /// セマンティックモデルを作成する /// </summary> /// <returns>作成結果</returns> private List <SemanticModel> CreateModels() { // C#ファイル情報リストを取得 var csFiles = CSFile.GetCSFileList(RootPath, FileRepository); // 編集クラスを作成 var mscorlib = MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location); var treeList = csFiles.Select(info => CSharpSyntaxTree.ParseText(info.SourceCode, null, info.RelativePath)).ToList(); var compilation = CSharpCompilation.Create("", treeList, new[] { mscorlib }); // セマンティックモデルのリストを取得する var models = new List <SemanticModel>(); foreach (var model in treeList) { models.Add(compilation.GetSemanticModel(model)); } return(models); }
/// <summary> /// Convsert specified data table to cs file object /// </summary> /// <param name="dBName"></param> /// <param name="tableName"></param> /// <param name="comment"></param> /// <param name="impledInterface"></param> /// <returns></returns> CSFile ConvertTable(string dBName, string tableName, string comment, string[] impledInterface) { CSFile writer = new CSFile(); string sqlString = string.Format("PRAGMA table_info([{0}]);", tableName); using (SQLiteCommand cmd = mSqliteConn.CreateCommand()) { cmd.CommandText = sqlString; //using writer.AddReferencedLib("System"); CSClass classObj = writer.AddCSClass("public", tableName, impledInterface); SQLiteDataAdapter da = new SQLiteDataAdapter(cmd); DataTable dt = new DataTable(); da.Fill(dt); DataColumn nameCol = dt.Columns["name"]; DataColumn typeCol = dt.Columns["type"]; CSParseFunc parseFunc = new CSParseFunc("public", tableName, "ReadData"); CSVar dataForm = parseFunc.AddParam(string.Empty, "ASteinGameDataHolder", "dataForm"); classObj.AddFuncDeclare(parseFunc); foreach (DataRow row in dt.Rows) { CSField dataVar = classObj.AddVar("public", SqliteType2CsType(row[typeCol].ToString()), row[nameCol].ToString()); CSFuncCall parseCall = new CSFuncCall(string.Empty, SqliteType2CsType(row[typeCol].ToString()), SqliteType2CsReadType(row[typeCol].ToString())); parseCall.AddParam("string", row[nameCol].ToString()); parseCall.targetObj = dataForm; parseCall.returnVar = dataVar; parseFunc.AddParseCall(parseCall); } } //System.Diagnostics.Trace.WriteLine(writer.GenerateFilsString()); return(writer); }
public string GenerateFrom(string workingDirectory, string assetName, DOMDocument document) { m_File = new CSFile(document.@namespace) .AddWarningDisable(414) .AddInclude("UnityEngine") .AddInclude("UnityEditor") .AddInclude("UnityEngine.Experimental") .AddInclude("UnityEditor.Experimental"); m_Class = new CSClass(Scope.Internal, assetName, CSClass.Modifier.Partial) .AddParent("StyleSheet"); m_File.AddClass(m_Class); Visit(document.styles); var builder = new StringBuilder(); m_File.GenerateIn(builder); return(builder.ToString()); }
public void Covert(Xml2CsConfig config) { CleanupOutput(config.outputPath); //get all xml files string[] files = Directory.GetFiles(config.xmlFileDir, "*.xml", SearchOption.AllDirectories); foreach (string xmlFile in files) { CSFile csFile = ConvertTable(xmlFile, config.CSdataClassImpledInterface); string filePath = config.outputPath + "/" + csFile.name + ".cs"; if (File.Exists(filePath)) { Console.WriteLine("{0} already exists.", filePath); return; } using (StreamWriter sw = File.CreateText(filePath)) { sw.Write(csFile.GenerateFilsString()); sw.Close(); } } System.Windows.Forms.MessageBox.Show("写入完毕!!!"); }
public static Stream BasicClass(string nameSpace, string className, CSMethod m, ClassMutator mutator, UsingMutator useMutator = null) { CSUsingPackages use = new CSUsingPackages("System"); if (useMutator != null) { use = useMutator(use); } CSClass cl = new CSClass(CSVisibility.Public, className, m != null ? new CSMethod [] { m } : null); if (mutator != null) { cl = mutator(cl); } CSNamespace ns = new CSNamespace(nameSpace); ns.Block.Add(cl); CSFile file = CSFile.Create(use, ns); return(CodeWriter.WriteToStream(file)); }
public static void TestAndExecute(string swiftCode, CodeElementCollection <ICodeElement> callingCode, string expectedOutput, string testName = null, CSClass otherClass = null, string skipReason = null, string iosExpectedOutput = null, PlatformName platform = PlatformName.None, UnicodeMapper unicodeMapper = null, int expectedErrorCount = 0, Action <string> postCompileCheck = null, string[] expectedOutputContains = null) { SetInvokingTestNameIfUnset(ref testName, out string nameSpace); string testClassName = "TomTest" + testName; using (var provider = new DisposableTempDirectory()) { var compiler = Utils.CompileSwift(swiftCode, provider, nameSpace); var libName = $"lib{nameSpace}.dylib"; var tempDirectoryPath = Path.Combine(provider.DirectoryPath, "BuildDir"); Directory.CreateDirectory(tempDirectoryPath); File.Copy(Path.Combine(compiler.DirectoryPath, libName), Path.Combine(tempDirectoryPath, libName)); Utils.CompileToCSharp(provider, tempDirectoryPath, nameSpace, unicodeMapper: unicodeMapper, expectedErrorCount: expectedErrorCount); if (postCompileCheck != null) { postCompileCheck(tempDirectoryPath); } Tuple <CSNamespace, CSUsingPackages> testClassParts = TestRunningCodeGenerator.CreateTestClass(callingCode, testName, iosExpectedOutput ?? expectedOutput, nameSpace, testClassName, otherClass, skipReason, platform); var thisTestPath = Path.Combine(Compiler.kSwiftDeviceTestRoot, nameSpace); Directory.CreateDirectory(thisTestPath); var thisTestPathSwift = Path.Combine(thisTestPath, "swiftsrc"); Directory.CreateDirectory(thisTestPathSwift); var swiftPrefix = string.Empty; var swiftSuffix = string.Empty; var csPrefix = string.Empty; var csSuffix = string.Empty; var nameSuffix = string.Empty; switch (platform) { case PlatformName.macOS: swiftPrefix = "#if os(OSX)\n"; swiftSuffix = "#endif\n"; csPrefix = "#if __MACOS__\n"; csSuffix = "\n#endif\n"; nameSuffix = "_macOS"; break; case PlatformName.iOS: swiftPrefix = "#if os(iOS)\n"; swiftSuffix = "#endif\n"; csPrefix = "#if __IOS__\n"; csSuffix = "\n#endif\n"; nameSuffix = "_iOS"; break; case PlatformName.tvOS: swiftPrefix = "#if os(tvOS)\n"; swiftSuffix = "#endif\n"; csPrefix = "#if __TVOS__\n"; csSuffix = "\n#endif\n"; nameSuffix = "_tvOS"; break; case PlatformName.watchOS: swiftPrefix = "#if os(watchOS)\n"; swiftSuffix = "#endif\n"; csPrefix = "#if __WATCHOS__\n"; csSuffix = "\n#endif\n"; nameSuffix = "_watchOS"; break; case PlatformName.None: break; default: throw new NotImplementedException(platform.ToString()); } File.WriteAllText(Path.Combine(thisTestPathSwift, $"{testClassName}{testName}{nameSuffix}.swift"), swiftPrefix + swiftCode + swiftSuffix); CSFile csTestFile = CSFile.Create(testClassParts.Item2, testClassParts.Item1); var csTestFilePath = Path.Combine(thisTestPath, $"{testClassName}{testName}{nameSuffix}.cs"); // Write out the file without csPrefix/csSuffix CodeWriter.WriteToFile(csTestFilePath, csTestFile); if (!string.IsNullOrEmpty(csPrefix) || !string.IsNullOrEmpty(csSuffix)) { // Read the C# code, and prepend/append the csPrefix/csSuffix blobs, then save the modified contents again. File.WriteAllText(csTestFilePath, csPrefix + File.ReadAllText(csTestFilePath) + csSuffix); } var csFile = TestRunningCodeGenerator.GenerateTestEntry(callingCode, testName, nameSpace, platform, otherClass); csFile.Namespaces.Add(CreateManagedConsoleRedirect()); CodeWriter.WriteToFile(Path.Combine(tempDirectoryPath, "NameNotImportant.cs"), csFile); var sourceFiles = Directory.GetFiles(tempDirectoryPath, "*.cs"); var objcRuntimePath = Path.Combine(tempDirectoryPath, "ObjCRuntime"); if (Directory.Exists(objcRuntimePath)) { sourceFiles = sourceFiles.And(Directory.GetFiles(objcRuntimePath, "*.cs")); } var compilerWarnings = Compiler.CSCompile(tempDirectoryPath, sourceFiles, "NameNotImportant.exe", platform: platform); if (compilerWarnings.Contains("warning")) { FailOnBadWarnings(compilerWarnings); } CopyTestReferencesTo(tempDirectoryPath, platform); var output = Execute(tempDirectoryPath, "NameNotImportant.exe", platform); if (expectedOutput != null) { Assert.AreEqual(expectedOutput, output); } else { foreach (var s in expectedOutputContains) { Assert.IsTrue(output.Contains(s), $"Expected to find string {s} in {output}"); } } } }
static CSFile GeneratePInvokesFromTypes(TypeAggregator types, PlatformName platform, string framework) { var fileName = Path.GetFileNameWithoutExtension(framework); // /path/XamGlue.framework -> XamGlue var dylibFile = Path.Combine(framework, fileName); var funcs = TLFunctionsForFile(dylibFile, platform); var ns = new CSNamespace("SwiftRuntimeLibrary.SwiftMarshal"); var use = new CSUsingPackages(); use.And(new CSUsing("System.Runtime.InteropServices")) .And(new CSUsing("System")) .And(new CSUsing("System.Collections.Generic")) .And(new CSUsing("SwiftRuntimeLibrary")); var csFile = new CSFile(use, new CSNamespace [] { ns }); var csClass = new CSClass(CSVisibility.Internal, $"{fileName}Metadata"); new CSComment(kRobotText).AttachBefore(use); CSConditionalCompilation.If(PlatformToCSCondition(platform)).AttachBefore(use); CSConditionalCompilation.Endif.AttachAfter(ns); ns.Block.Add(csClass); var typeOntoPinvoke = new List <KeyValuePair <CSBaseExpression, CSBaseExpression> > (); var typesToProcess = new List <TypeDefinition> (); typesToProcess.AddRange(types.PublicEnums); typesToProcess.AddRange(types.PublicStructs); // pre-sort by function name typesToProcess.Sort((type1, type2) => String.CompareOrdinal(FuncIDForTypeDefinition(type1), FuncIDForTypeDefinition(type2))); foreach (var type in typesToProcess) { if (type.HasGenericParameters) { continue; } var moduleName = type.Namespace; var name = type.Name; if (TypeAggregator.FilterModuleAndName(platform, moduleName, ref name)) { var pinvoke = PInvokeForType(type, funcs); if (pinvoke != null) { csClass.Methods.Add(pinvoke); use.AddIfNotPresent(type.Namespace); var typeOf = new CSSimpleType(type.FullName).Typeof(); var funcName = pinvoke.Name; typeOntoPinvoke.Add(new KeyValuePair <CSBaseExpression, CSBaseExpression> (typeOf, funcName)); } } } var initializers = typeOntoPinvoke.Select(typeAndFunc => new CSInitializer(new CSBaseExpression [] { typeAndFunc.Key, typeAndFunc.Value }, false)); var bindingExpr = new CSInitializedType(new CSFunctionCall("Dictionary<Type, Func<SwiftMetatype>>", true), new CSInitializer(initializers, true)); var bindingDecl = new CSFieldDeclaration(new CSSimpleType("Dictionary<Type, Func<SwiftMetatype>>"), "ObjCBindingSwiftMetatypes", bindingExpr, CSVisibility.Internal, true); csClass.Fields.Add(new CSLine(bindingDecl)); use.Sort((package1, package2) => String.CompareOrdinal(package1.Package, package2.Package)); return(csFile); }
/// <summary> /// Creates a list of all types, and a hash table which is initialized on first lookup from C# type /// to Swift types. /// </summary> /// <param name="types">Aggregated types, a subset of which are included</param> /// <param name="platform">Platform targeted (typically iOS or Mac)</param> /// <param name="namespaces">Namespaces to include</param> /// <param name="framework">Name of framework used (typically XamGlue)</param> /// <returns>CSFile which, when written, has function looking up in hash table as described in summary</returns> static CSFile GenerateCSharpHashTableFromTypes(TypeAggregator types, PlatformName platform, List <string> namespaces, string framework) { var fileName = Path.GetFileNameWithoutExtension(framework); var ns = new CSNamespace("SwiftRuntimeLibrary.SwiftMarshal"); var use = new CSUsingPackages(); use.And(new CSUsing("System.Runtime.InteropServices")) .And(new CSUsing("System")) .And(new CSUsing("System.Collections.Generic")) .And(new CSUsing("SwiftRuntimeLibrary")); var csFile = new CSFile(use, new CSNamespace [] { ns }); var csClass = new CSClass(CSVisibility.Internal, $"{fileName}Metadata"); new CSComment(kRobotText).AttachBefore(use); CSConditionalCompilation.If(PlatformToCSCondition(platform)).AttachBefore(use); CSConditionalCompilation.Endif.AttachAfter(ns); ns.Block.Add(csClass); // collect all possible types, filter and sort var selectedTypes = new List <TypeDefinition> (); selectedTypes.AddRange(types.PublicEnums); selectedTypes.AddRange(types.PublicStructs); selectedTypes = selectedTypes.FindAll(type => IncludeType(type, namespaces, platform)); selectedTypes.Sort((type1, type2) => String.CompareOrdinal(type1.FullName, type2.FullName)); // add used namespaces to import list, sort list foreach (var type in selectedTypes) { use.AddIfNotPresent(type.Namespace); } use.Sort((package1, package2) => String.CompareOrdinal(package1.Package, package2.Package)); // create list of types to translate var typesForList = selectedTypes.Select(type => new CSSimpleType(type.FullName).Typeof()); var listInitializeExpr = new CSInitializedType( new CSFunctionCall("List<Type>", true), new CSInitializer(typesForList, true) ); var listBindingDecl = new CSFieldDeclaration(new CSSimpleType("List<Type>"), "csImportTypes", listInitializeExpr, CSVisibility.Internal, true); csClass.Fields.Add(new CSLine(listBindingDecl)); // create pinvoke for function var dylibFile = Path.Combine(framework, fileName); var funcs = TLFunctionsForFile(dylibFile, platform); var handleTranslationCode = new CSIdentifier(@" public static unsafe bool GetSwiftType (Type t, out SwiftMetatype md) { using (var swiftStr = new SwiftString (t.FullName)) { return SwiftCore.GetEnumMetadataByName (swiftStr.SwiftData, out md); } } internal static Dictionary<Type, SwiftMetatype> csImportMeta = null; internal static bool TryGetImportedMetadata (Type cSharpType, out SwiftMetatype md) { if (csImportMeta == null) { csImportMeta = new Dictionary<Type, SwiftMetatype> (csImportTypes.Count); foreach (var t in csImportTypes) { SwiftMetatype meta; GetSwiftType(t, out meta); csImportMeta [t] = meta; } } return csImportMeta.TryGetValue (cSharpType, out md); }" ); csClass.Fields.Add(new CSLine(handleTranslationCode, false)); return(csFile); }
/// <summary> /// this will return a SortedList, the key is the interface name, /// and the value is the type definition of the class that implements that interface; /// connectors are identified namespace ending with Connectors /// </summary> private static SortedList <string, TypeDeclaration> GetConnectors(List <CSParser> ACSFiles) { SortedList <string, TypeDeclaration> Result = new SortedList <string, TypeDeclaration>(); foreach (CSParser CSFile in ACSFiles) { foreach (TypeDeclaration t in CSFile.GetClasses()) { if (t.UserData.ToString().EndsWith("Connectors")) { string Interface = CSParser.GetImplementedInterface(t); if (Interface.Length > 0) { string ServerNamespace = t.UserData.ToString(); string ServerNamespaceWithClassName = ServerNamespace + "." + t.Name; string key = ServerNamespaceWithClassName + ":" + Interface; if (Result.ContainsKey(ServerNamespaceWithClassName)) { // there is already the other part of the partial class TypeDeclaration partialType = Result[ServerNamespaceWithClassName]; Result.Remove(ServerNamespaceWithClassName); foreach (INode child in partialType.Children) { t.AddChild(child); } } Result.Add(key, t); if (TLogging.DebugLevel > 1) { // TLogging.Log("adding new Connector " + key); } } // either a webconnector, or a partial class else { // web connectors don't derive from an interface, because the methods are static string ServerNamespace = t.UserData.ToString(); string key = ServerNamespace + "." + t.Name; if (Result.ContainsKey(key)) { // partial class foreach (INode child in t.Children) { Result[key].AddChild(child); } } else if (t.Name.EndsWith("UIConnector")) { // this could be the partial class of a UIConnector // try to find a key that starts with this type bool foundType = false; foreach (string k in Result.Keys) { if (k.StartsWith(key + ":")) { foundType = true; foreach (INode child in t.Children) { Result[k].AddChild(child); } } } if (!foundType) { Result.Add(key, t); } } else { Result.Add(key, t); } if (TLogging.DebugLevel > 1) { // TLogging.Log("adding new Connector " + key); } } } } } return(Result); }