Esempio n. 1
0
        private void ParseFile(string filename, Version apiVersion)
        {
            var document = ApiNode.Load(filename);
            var section  = document?.SelectOne(@"//div.content/div.section");
            var header   = section?.SelectOne(@"div.mb20.clear");
            var name     = header?.SelectOne(@"h1.heading.inherit"); // Type or type member name
            var ns       = header?.SelectOne(@"p");                  // "class in {ns}"

            // Only interested in types at this point
            if (name == null || ns == null)
            {
                return;
            }

            // Only types that have messages
            var messages = section.Subsection("Messages").ToArray();

            if (messages.Length == 0)
            {
                return;
            }

            var match   = NsRegex.Match(ns.Text);
            var clsType = match.Groups["type"].Value;
            var nsName  = match.Groups["namespace"].Value;

            var unityApiType = api.AddType(nsName, name.Text, clsType, filename, apiVersion);

            foreach (var message in messages)
            {
                var eventFunction = ParseMessage(message, apiVersion, nsName);
                unityApiType.MergeEventFunction(eventFunction, apiVersion);
            }
        }
Esempio n. 2
0
        private UnityApiEventFunction ParseMessage(ApiNode message, Version apiVersion, string hintNamespace)
        {
            var link = message.SelectOne(@"td.lbl/a");
            var desc = message.SelectOne(@"td.desc");

            if (link == null || desc == null)
            {
                return(null);
            }

            var detailsPath = link[@"href"];

            if (string.IsNullOrWhiteSpace(detailsPath))
            {
                return(null);
            }

            var path = Path.Combine(myScriptReferenceRelativePath, detailsPath);

            if (!File.Exists(path))
            {
                return(null);
            }

            var detailsDoc = ApiNode.Load(path);
            var details    = detailsDoc?.SelectOne(@"//div.content/div.section");
            var signature  = details?.SelectOne(@"div.mb20.clear/h1.heading.inherit");
            var staticNode = details?.SelectOne(@"div.subsection/p/code.varname[text()='static']");

            if (signature == null)
            {
                return(null);
            }

            var isCoroutine = CoroutineRegex.IsMatch(details.Text);

            var messageName = link.Text;
            var returnType  = ApiType.Void;

            string[] argumentNames       = null;
            var      isStaticFromExample = false;

            var example = PickExample(details);

            if (example != null)
            {
                var tuple = ParseDetailsFromExample(messageName, example, hintNamespace);
                returnType          = tuple.Item1;
                argumentNames       = tuple.Item2;
                isStaticFromExample = tuple.Item3;
            }

            var docPath       = Path.Combine(myScriptReferenceRelativePath, detailsPath);
            var eventFunction = new UnityApiEventFunction(messageName, staticNode != null || isStaticFromExample, isCoroutine,
                                                          returnType, apiVersion, desc.Text, docPath);

            ParseParameters(eventFunction, signature, details, hintNamespace, argumentNames);

            return(eventFunction);
        }
Esempio n. 3
0
        private void ParseFile([NotNull] string filename)
        {
            var document = ApiNode.Load(filename);
            var section  = document?.SelectOne(@"//div.content/div.section");
            var header   = section?.SelectOne(@"div.mb20.clear");
            var cls      = header?.SelectOne(@"h1.heading.inherit");
            var ns       = header?.SelectOne(@"p");

            if (cls == null || ns == null)
            {
                return;
            }

            var messages = section.Subsection("Messages").ToArray();

            if (messages.Length == 0)
            {
                return;
            }

            api.Enter("type");

            var clsType = NsRegex.Replace(ns.Text, "$1");

            api.SetAttribute("kind", clsType);
            api.SetAttribute("name", cls.Text);

            var nsName = NsRegex.Replace(ns.Text, "$2");

            api.SetAttribute(@"ns", nsName);

            var hostType = new ApiType(string.Concat(nsName, ".", cls.Text));

            api.SetAttribute("path", new Uri(filename).AbsoluteUri);

            foreach (var message in messages)
            {
                string  detailsPath;
                ApiType type;
                if (!ParseMessage(message, out detailsPath, out type))
                {
                    continue;
                }

                api.LeaveTo("message");
                api.SetAttribute("path", new Uri(detailsPath).AbsoluteUri);

                api.Enter("returns");
                api.SetAttribute("type", type.FullName);
                api.SetAttribute("array", type.IsArray);
            }
        }
Esempio n. 4
0
        private static ApiNode[] PickExample([NotNull] ApiNode details)
        {
            // Favour C#, it's the most strongly typed
            var examples = PickExample(details, "CS");

            if (examples.IsEmpty())
            {
                examples = PickExample(details, "JS");
            }
            if (examples.IsEmpty())
            {
                examples = PickExample(details, "Raw");
            }
            return(examples);
        }
Esempio n. 5
0
        private static void ParseMessageExample(string messageName, IReadOnlyList <Argument> arguments,
                                                ApiNode example, ref ApiType type)
        {
            var blankCleanup1 = new Regex(@"\s+");
            var blankCleanup2 = new Regex(@"\s*(\W)\s*");

            var exampleText = example.Text;

            exampleText = blankCleanup1.Replace(exampleText, " ");
            exampleText = blankCleanup2.Replace(exampleText, "$1");

            var jsRegex = new Regex($@"(?:\W|^)function {messageName}\(([^)]*)\)(?::(\w+))?\{{");
            var m       = jsRegex.Match(exampleText);

            if (m.Success)
            {
                type = new ApiType(m.Groups[2].Value);
                var parameters = m.Groups[1].Value.Split(',');

                for (var i = 0; i < arguments.Count; ++i)
                {
                    arguments[i].Name = parameters[i].Split(':')[0];
                }

                return;
            }

            var csRegex = new Regex($@"(\w+) {messageName}\(([^)]*)\)");

            m = csRegex.Match(exampleText);
            if (m.Success)
            {
                var nameRegex = new Regex(@"\W(\w+)$");

                type = new ApiType(m.Groups[1].Value);
                var parameters = m.Groups[2].Value.Split(',');
                for (var i = 0; i < arguments.Count; ++i)
                {
                    arguments[i].Name = nameRegex.Replace(parameters[i], "$1");
                }

                return;
            }

            Console.WriteLine(exampleText);
        }
Esempio n. 6
0
        private static void ResolveArguments([NotNull] ApiNode details, [NotNull] IReadOnlyList <Argument> arguments, string[] argumentNames)
        {
            for (var i = 0; i < arguments.Count && i < argumentNames.Length; i++)
            {
                if (!string.IsNullOrEmpty(argumentNames[i]))
                {
                    arguments[i].Name = argumentNames[i];
                }
            }

            var parameters = details.Subsection("Parameters").ToArray();

            if (Enumerable.Any(parameters))
            {
                ParseMessageParameters(arguments, parameters);
            }
        }
Esempio n. 7
0
        private static void ResolveArguments([NotNull] string message, [NotNull] ApiNode details,
                                             [NotNull] IReadOnlyList <Argument> arguments, [NotNull] ref ApiType type)
        {
            var parameters = details.Subsection("Parameters").ToArray();

            if (parameters.Any())
            {
                ParseMessageParameters(arguments, parameters);
                return;
            }

            var example = PickExample(details);

            if (example == null)
            {
                return;
            }

            ParseMessageExample(message, arguments, example, ref type);
        }
Esempio n. 8
0
        private static void ParseParameters(UnityApiEventFunction eventFunction, ApiNode signature, ApiNode details, string owningMessageNamespace, string[] argumentNames)
        {
            // Capture the arguments string. Note that this might be `string s, int i` or `string, int`
            var match = CaptureArgumentsRegex.Match(signature.Text);

            if (!match.Success)
            {
                return;
            }

            var argumentString  = match.Groups["args"].Value;
            var argumentStrings = argumentString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                  .Select(s => s.Trim())
                                  .ToArray();
            var total     = argumentStrings.Length;
            var arguments = argumentStrings.Select((s, i) => new Argument(s, i, total, owningMessageNamespace)).ToArray();

            ResolveArguments(details, arguments, argumentNames);

            foreach (var argument in arguments)
            {
                eventFunction.AddParameter(argument.Name, argument.Type, argument.Description);
            }
        }
Esempio n. 9
0
        private static void ParseParameters(UnityApiEventFunction eventFunction, ApiNode signature, ApiNode details, string owningMessageNamespace, string[] argumentNames)
        {
            // E.g. OnCollisionExit2D(Collision2D) - doesn't always include the argument name
            // Hopefully, we parsed the argument name from the example
            var argumentString = SigRegex.Replace(signature.Text, "$2$3");

            if (string.IsNullOrWhiteSpace(argumentString))
            {
                return;
            }

            var argumentStrings = argumentString.Split(',')
                                  .Select(s => s.Trim())
                                  .ToArray();
            var total     = argumentStrings.Length;
            var arguments = argumentStrings.Select((s, i) => new Argument(s, i, total, owningMessageNamespace)).ToArray();

            ResolveArguments(details, arguments, argumentNames);

            foreach (var argument in arguments)
            {
                eventFunction.AddParameter(argument.Name, argument.Type, argument.Description);
            }
        }
Esempio n. 10
0
 private static ApiNode PickExample([NotNull] ApiNode details)
 {
     return(PickExample(details, "Raw") ?? PickExample(details, "JS") ?? PickExample(details, "CS"));
 }
Esempio n. 11
0
        private void ParseFile(string filename, Version apiVersion, HashSet <string> processed)
        {
            if (processed.Contains(filename))
            {
                return;
            }

            processed.Add(filename);

            // We're only interested in the file if it contains messages. Bail early
            // so we don't have to parse it to HTML
            var content = File.ReadAllText(filename);

            if (!content.Contains("Messages"))
            {
                return;
            }

            var document = ApiNode.LoadContent(content);
            var section  = document?.SelectOne(@"//div.content/div.section");
            var header   = section?.SelectOne(@"div.mb20.clear");
            var removed  = header?.SelectOne(@"div[@class='message message-error mb20']");
            var name     = header?.SelectOne(@"h1.heading.inherit"); // Type or type member name
            var ns       = header?.SelectOne(@"p");                  // "class in {ns}"/"struct in {ns}"/"Namespace: {ns}"

            // Only interested in types at this point
            if (name == null || ns == null)
            {
//                Console.WriteLine("File has no types: {0}", filename);
                return;
            }

            // Only types that have messages
            var messages = section.Subsection("Messages").ToArray();

            if (messages.Length == 0)
            {
                return;
            }

            var match   = CaptureKindAndNamespaceRegex.Match(ns.Text);
            var clsType = match.Groups["type"].Value;
            var nsName  = match.Groups["namespace"].Value;

            if (string.IsNullOrEmpty(clsType))
            {
                clsType = "class";
            }
            if (string.IsNullOrEmpty(nsName))
            {
                // Quick fix up for the 5.0 docs, which don't specify a namespace for AssetModificationProcessor
                if (apiVersion == new Version(5, 0) && name.Text == "AssetModificationProcessor")
                {
                    nsName = "UnityEditor";
                }
                else
                {
                    Console.WriteLine("Missing namespace: {0}", name.Text);
                    return;
                }
            }

            if (removed != null && removed.Text.StartsWith("Removed"))
            {
                Console.WriteLine($"{nsName}.{name.Text} no longer available in {apiVersion}: {removed.Text}");
                return;
            }

            var unityApiType = myApi.AddType(nsName, name.Text, clsType, filename, apiVersion);

            foreach (var message in messages)
            {
                var eventFunction = ParseMessage(name.Text, message, apiVersion, nsName, processed);
                unityApiType.MergeEventFunction(eventFunction, apiVersion);
            }
        }
Esempio n. 12
0
        // Gets return type and argument names from example
        private static Tuple<ApiType, string[]> ParseDetailsFromExample(string messageName, ApiNode example, string owningMessageNamespace)
        {
            var blankCleanup1 = new Regex(@"\s+");
            var blankCleanup2 = new Regex(@"\s*(\W)\s*");

            var exampleText = example.Text;
            exampleText = blankCleanup1.Replace(exampleText, " ");
            exampleText = blankCleanup2.Replace(exampleText, "$1");

            var jsRegex = new Regex($@"(?:\W|^)function {messageName}\(([^)]*)\)(?::(\w+))?\{{");
            var m = jsRegex.Match(exampleText);
            if (m.Success)
            {
                var returnType = new ApiType(m.Groups[2].Value, owningMessageNamespace);
                var parameters = m.Groups[1].Value.Split(',');

                var arguments = new string[parameters.Length];
                for (var i = 0; i < parameters.Length; ++i)
                {
                    arguments[i] = parameters[i].Split(':')[0];
                }

                return Tuple.Create(returnType, arguments);
            }

            var csRegex = new Regex($@"(\w+) {messageName}\(([^)]*)\)");
            m = csRegex.Match(exampleText);
            if (m.Success)
            {
                var nameRegex = new Regex(@"\W(\w+)$");

                var returnType = new ApiType(m.Groups[1].Value, owningMessageNamespace);
                var parameters = m.Groups[2].Value.Split(',');

                var arguments = new string[parameters.Length];
                for (var i = 0; i < parameters.Length; ++i)
                {
                    arguments[i] = nameRegex.Replace(parameters[i], "$1");
                }

                return Tuple.Create(returnType, arguments);
            }

            return null;
        }
Esempio n. 13
0
 private static ApiNode[] PickExample([NotNull] ApiNode details, [NotNull] string type)
 {
     return(details.SelectMany($@"div.subsection/pre.codeExample{type}"));
 }
Esempio n. 14
0
        private static Tuple <ApiType, string[], bool> ParseDetailsFromExample(string messageName, ApiNode example, string owningMessageNamespace)
        {
            // Grr. This took far too long to figure out...
            // The example for OnProjectChange uses "OnProjectChanged" instead
            // https://docs.unity3d.com/ScriptReference/EditorWindow.OnProjectChange.html
            if (messageName == "OnProjectChange" && example.Text.Contains("OnProjectChanged"))
            {
                messageName = "OnProjectChanged";
            }

            var exampleText = example.Text;

            exampleText = SingleLineCommentsRegex.Replace(exampleText, string.Empty);
            exampleText = BlankCleanup1.Replace(exampleText, " ");
            exampleText = BlankCleanup2.Replace(exampleText, "$1");
            exampleText = ArrayFixup.Replace(exampleText, "$1 $2");

            // This matches both C# and JS function signatures
            var functionRegex = new Regex($@"(?:\W|^)(?<static>static\s+)?(?<returnType>\w+\W*)\s+{messageName}\((?<parameters>[^)]*)\)(?::(?<returnType>\w+\W*))?{{");
            var m             = functionRegex.Match(exampleText);

            if (m.Success)
            {
                var returnTypeName = m.Groups["returnType"].Value;
                if (returnTypeName == "function") // JS without an explicit return type
                {
                    returnTypeName = "void";
                }
                var returnType = new ApiType(returnTypeName, owningMessageNamespace);
                var parameters = m.Groups["parameters"].Value
                                 .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                var isStatic = m.Groups["static"].Success;

                var arguments = new string[parameters.Length];
                for (var i = 0; i < parameters.Length; ++i)
                {
                    if (parameters[i].Contains(":"))
                    {
                        arguments[i] = parameters[i].Split(':')[0];
                    }
                    else
                    {
                        arguments[i] = ParameterNameRegex.Replace(parameters[i], "$1");
                    }
                }

                return(Tuple.Create(returnType, arguments, isStatic));
            }

            return(null);
        }
Esempio n. 15
0
        private bool ParseMessage([NotNull] ApiNode message, out string path, out ApiType type)
        {
            path = string.Empty;
            type = new ApiType("void");

            var link = message.SelectOne(@"td.lbl/a");
            var desc = message.SelectOne(@"td.desc");

            if (link == null || desc == null)
            {
                return(false);
            }

            var detailsPath = link[@"href"];

            if (string.IsNullOrWhiteSpace(detailsPath))
            {
                return(false);
            }

            path = Path.Combine(rootPath, detailsPath);
            if (!File.Exists(path))
            {
                return(false);
            }

            var detailsDoc = ApiNode.Load(path);
            var details    = detailsDoc?.SelectOne(@"//div.content/div.section");
            var signature  = details?.SelectOne(@"div.mb20.clear/h1.heading.inherit");
            var staticNode = details?.SelectOne(@"div.subsection/p/code.varname[text()='static']");

            if (signature == null)
            {
                return(false);
            }

            api.Enter("message");
            api.SetAttribute("name", link.Text);
            api.SetAttribute("static", staticNode != null);
            var description = desc.Text;

            if (!string.IsNullOrWhiteSpace(description))
            {
                api.SetAttribute("description", description);
            }

            // E.g. OnCollisionExit2D(Collision2D)
            var argumentString = SigRegex.Replace(signature.Text, "$2$3");

            if (string.IsNullOrWhiteSpace(argumentString))
            {
                return(true);
            }

            var argumentStrings = argumentString.Split(',')
                                  .Select(s => s.Trim())
                                  .ToArray();
            var total     = argumentStrings.Length;
            var arguments = argumentStrings.Select((s, i) => new Argument(s, i, total)).ToArray();

            ResolveArguments(link.Text, details, arguments, ref type);

            api.Enter("parameters");
            foreach (var argument in arguments)
            {
                api.Enter("parameter");

                api.SetAttribute("type", argument.Type.FullName);
                api.SetAttribute("array", argument.Type.IsArray);
                api.SetAttribute("name", argument.Name);
                if (!string.IsNullOrWhiteSpace(argument.Description))
                {
                    api.SetAttribute("description", argument.Description);
                }
            }

            return(true);
        }
Esempio n. 16
0
        private static void ParseParameters(UnityApiEventFunction  eventFunction, ApiNode signature, ApiNode details, string owningMessageNamespace, string[] argumentNames)
        {
            // E.g. OnCollisionExit2D(Collision2D) - doesn't always include the argument name
            // Hopefully, we parsed the argument name from the example
            var argumentString = SigRegex.Replace(signature.Text, "$2$3");
            if (string.IsNullOrWhiteSpace(argumentString)) return;

            var argumentStrings = argumentString.Split(',')
                .Select(s => s.Trim())
                .ToArray();
            var total = argumentStrings.Length;
            var arguments = argumentStrings.Select((s, i) => new Argument(s, i, total, owningMessageNamespace)).ToArray();

            ResolveArguments(details, arguments, argumentNames);

            foreach (var argument in arguments)
                eventFunction.AddParameter(argument.Name, argument.Type, argument.Description);
        }
Esempio n. 17
0
        private static ApiNode PickExample([NotNull] ApiNode details, [NotNull] string type)
        {
            var example = details.SelectOne($@"div.subsection/pre.codeExample{type}");

            return(example == null || example.Text.StartsWith("no example available") ? null : example);
        }
Esempio n. 18
0
        // Gets return type and argument names from example
        private static Tuple <ApiType, string[]> ParseDetailsFromExample(string messageName, ApiNode example, string owningMessageNamespace)
        {
            var blankCleanup1 = new Regex(@"\s+");
            var blankCleanup2 = new Regex(@"\s*(\W)\s*");

            var exampleText = example.Text;

            exampleText = blankCleanup1.Replace(exampleText, " ");
            exampleText = blankCleanup2.Replace(exampleText, "$1");

            var jsRegex = new Regex($@"(?:\W|^)function {messageName}\(([^)]*)\)(?::(\w+))?\{{");
            var m       = jsRegex.Match(exampleText);

            if (m.Success)
            {
                var returnType = new ApiType(m.Groups[2].Value, owningMessageNamespace);
                var parameters = m.Groups[1].Value.Split(',');

                var arguments = new string[parameters.Length];
                for (var i = 0; i < parameters.Length; ++i)
                {
                    arguments[i] = parameters[i].Split(':')[0];
                }

                return(Tuple.Create(returnType, arguments));
            }

            var csRegex = new Regex($@"(\w+) {messageName}\(([^)]*)\)");

            m = csRegex.Match(exampleText);
            if (m.Success)
            {
                var nameRegex = new Regex(@"\W(\w+)$");

                var returnType = new ApiType(m.Groups[1].Value, owningMessageNamespace);
                var parameters = m.Groups[2].Value.Split(',');

                var arguments = new string[parameters.Length];
                for (var i = 0; i < parameters.Length; ++i)
                {
                    arguments[i] = nameRegex.Replace(parameters[i], "$1");
                }

                return(Tuple.Create(returnType, arguments));
            }

            return(null);
        }
Esempio n. 19
0
        // Gets return type and argument names from example
        private static Tuple <ApiType, string[], bool> ParseDetailsFromExample(string messageName, ApiNode example, string owningMessageNamespace)
        {
            var blankCleanup1 = new Regex(@"\s+");
            var blankCleanup2 = new Regex(@"\s*(\W)\s*");
            var arrayFixup    = new Regex(@"(\[\])(\w)");

            var exampleText = example.Text;

            exampleText = blankCleanup1.Replace(exampleText, " ");
            exampleText = blankCleanup2.Replace(exampleText, "$1");
            exampleText = arrayFixup.Replace(exampleText, "$1 $2");

            var jsRegex = new Regex($@"(?:\W|^)(?<static>static\s+)?function {messageName}\((?<parameters>[^)]*)\)(?::(?<returnType>\w+\W*))?\{{");
            var m       = jsRegex.Match(exampleText);

            if (m.Success)
            {
                var returnType = new ApiType(m.Groups["returnType"].Value, owningMessageNamespace);
                var parameters = m.Groups["parameters"].Value.Split(',');
                var isStatic   = m.Groups["static"].Success;

                var arguments = new string[parameters.Length];
                for (var i = 0; i < parameters.Length; ++i)
                {
                    arguments[i] = parameters[i].Split(':')[0];
                }

                return(Tuple.Create(returnType, arguments, isStatic));
            }

            var csRegex = new Regex($@"(?:\W|^)(?<static>static\s+)?(?<returnType>\w+\W*) {messageName}\((?<parameters>[^)]*)\)");

            m = csRegex.Match(exampleText);
            if (m.Success)
            {
                var nameRegex = new Regex(@"^.*?\W(\w+)$");

                var returnType = new ApiType(m.Groups["returnType"].Value, owningMessageNamespace);
                var parameters = m.Groups["parameters"].Value.Split(',');
                var isStatic   = m.Groups["static"].Success;

                var arguments = new string[parameters.Length];
                for (var i = 0; i < parameters.Length; ++i)
                {
                    arguments[i] = nameRegex.Replace(parameters[i], "$1");
                }

                return(Tuple.Create(returnType, arguments, isStatic));
            }

            return(null);
        }
Esempio n. 20
0
        private UnityApiEventFunction ParseMessage(string className, ApiNode message, Version apiVersion,
                                                   string hintNamespace, HashSet <string> processed)
        {
            var link = message.SelectOne(@"td.lbl/a");
            var desc = message.SelectOne(@"td.desc");

            if (link == null || desc == null)
            {
                return(null);
            }

            var detailsPath = link[@"href"];

            if (string.IsNullOrWhiteSpace(detailsPath))
            {
                return(null);
            }

            var scriptReferenceRelativePath = Directory.Exists(ScriptReferenceRelativePath1)
                ? ScriptReferenceRelativePath1
                : ScriptReferenceRelativePath2;
            var path = Path.Combine(scriptReferenceRelativePath, detailsPath);

            processed.Add(path);
            if (!File.Exists(path))
            {
                return(null);
            }

            var detailsDoc = ApiNode.Load(path);
            var details    = detailsDoc?.SelectOne(@"//div.content/div.section");
            var signature  = details?.SelectOne(@"div.mb20.clear/h1.heading.inherit");
            var staticNode = details?.SelectOne(@"div.subsection/p/code.varname[text()='static']");

            if (signature == null)
            {
                return(null);
            }

            var isCoroutine = IsCoroutineRegex.IsMatch(details.Text);

            var messageName         = link.Text;
            var returnType          = ApiType.Void;
            var argumentNames       = EmptyArray <string> .Instance;
            var isStaticFromExample = false;

            var examples = PickExample(details);

            if (examples.Length > 0)
            {
                var tuple = ParseDetailsFromExample(messageName, examples, hintNamespace);

                // As of 2017.4, the docs for MonoBehaviour.OnCollisionEnter2D don't include a valid example. It demonstrates
                // OnTriggerEnter2D instead. Similar problems for these other methods
                if (tuple == null)
                {
                    var fullName = $"{className}.{messageName}";
                    switch (fullName)
                    {
                    case "MonoBehaviour.OnCollisionEnter2D":
                    case "MonoBehaviour.OnCollisionExit2D":
                    case "MonoBehaviour.OnCollisionStay2D":
                    case "MonoBehaviour.Start":
                    case "MonoBehaviour.OnDestroy":
                        Console.WriteLine(
                            $"WARNING: Unable to parse example for {fullName}. Example incorrect in docs");
                        break;

//                        case "Network.OnDisconnectedFromServer":
//                            Bug in 2018.2 documentation
//                            Console.WriteLine($"WARNING: Missing example for {fullName}");
//                            break;

                    default:
                        foreach (var example in examples)
                        {
                            Console.WriteLine(example.Text);
                            Console.WriteLine();
                        }

                        throw new InvalidOperationException($"Failed to parse example for {className}.{messageName}");
                    }
                }

                if (tuple != null)
                {
                    returnType          = tuple.Item1;
                    argumentNames       = tuple.Item2;
                    isStaticFromExample = tuple.Item3;
                }
            }

            if (Equals(returnType, ApiType.IEnumerator))
            {
                returnType  = ApiType.Void;
                isCoroutine = true;
            }

            var docPath       = Path.Combine(scriptReferenceRelativePath, detailsPath);
            var eventFunction = new UnityApiEventFunction(messageName, staticNode != null || isStaticFromExample,
                                                          isCoroutine, returnType, apiVersion, desc.Text, docPath);

            ParseParameters(eventFunction, signature, details, hintNamespace, argumentNames);

            return(eventFunction);
        }
Esempio n. 21
0
 private static ApiNode PickExample([NotNull] ApiNode details)
 {
     // Favour C#, it's the most strongly typed
     return(PickExample(details, "CS") ?? PickExample(details, "JS") ?? PickExample(details, "Raw"));
 }
Esempio n. 22
0
        private UnityApiEventFunction ParseMessage(ApiNode message, Version apiVersion, string hintNamespace)
        {
            var link = message.SelectOne(@"td.lbl/a");
            var desc = message.SelectOne(@"td.desc");
            if (link == null || desc == null) return null;

            var detailsPath = link[@"href"];
            if (string.IsNullOrWhiteSpace(detailsPath)) return null;

            var path = Path.Combine(myScriptReferenceRelativePath, detailsPath);
            if (!File.Exists(path)) return null;

            var detailsDoc = ApiNode.Load(path);
            var details = detailsDoc?.SelectOne(@"//div.content/div.section");
            var signature = details?.SelectOne(@"div.mb20.clear/h1.heading.inherit");
            var staticNode = details?.SelectOne(@"div.subsection/p/code.varname[text()='static']");

            if (signature == null) return null;

            var messageName = link.Text;
            var returnType = ApiType.Void;
            string[] argumentNames = null;

            var example = PickExample(details);
            if (example != null)
            {
                var tuple = ParseDetailsFromExample(messageName, example, hintNamespace);
                returnType = tuple.Item1;
                argumentNames = tuple.Item2;
            }

            var docPath = Path.Combine(myScriptReferenceRelativePath, detailsPath);
            var eventFunction = new UnityApiEventFunction(messageName, staticNode != null, returnType, apiVersion, desc.Text, docPath, false);

            ParseParameters(eventFunction, signature, details, hintNamespace, argumentNames);

            return eventFunction;
        }