Example #1
0
        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());
        }
Example #2
0
        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());
        }
Example #3
0
        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));
        }
Example #7
0
        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("写入完毕!!!");
        }
Example #8
0
        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);
                    }
                }
            }
        }
Example #9
0
        //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);
        }
Example #10
0
        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);
            }
        }
Example #11
0
        /// <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());
        }
    }
Example #15
0
        /// <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);
        }
Example #16
0
        /// <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);
        }
Example #17
0
        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());
        }
Example #18
0
        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("写入完毕!!!");
        }
Example #19
0
        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}");
                    }
                }
            }
        }
Example #21
0
        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);
        }
Example #22
0
        /// <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);
        }
Example #23
0
        /// <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);
        }