Esempio n. 1
0
        private IList <DocumentContext> ParseDocument(Uri uri,
                                                      IList <DocumentContext> contexts = null,
                                                      ISet <Uri> parsedUris            = null,
                                                      Stack <Uri> parentDocuments      = null,
                                                      TypeRegistry typeRegistry        = null)
        {
            // This is only for the first call.
            contexts        = contexts ?? new List <DocumentContext>();
            parsedUris      = parsedUris ?? new HashSet <Uri>();
            parentDocuments = parentDocuments ?? new Stack <Uri>();
            typeRegistry    = typeRegistry ?? new TypeRegistry();

            if (uri == null || !uri.IsAbsoluteUri)
            {
                throw new ArgumentException("Only absolute URIs can be parsed!");
            }
            if (parentDocuments.Contains(uri))
            {
                throw new ArgumentException(string.Format("Input {0} recursively includes itself ({1})", uri,
                                                          string.Join(" -> ", parentDocuments) + " -> " + uri));
            }

            LOG.Debug(string.Format("Parsing {0}...", uri));

            var idlNamespace = ExtractNamespace(uri);

            if (string.IsNullOrWhiteSpace(idlNamespace))
            {
                throw new ArgumentException(string.Format("URI {0} can not be translated to a namespace", uri));
            }

            var context = CreateDocumentContext(uri, idlNamespace, _generatorConfig, typeRegistry);

            var document = context.Document;
            var header   = document.Header;

            // Make a note that this document is a parent of all the documents included, directly or recursively
            parentDocuments.Push(uri);

            try
            {
                if (header != null)
                {
                    foreach (var include in header.Includes)
                    {
                        Uri includeUri;
                        Uri.TryCreate(_generatorConfig.InputBase, include, out includeUri);
                        ParseDocument(includeUri,
                                      // If the includes should also generate code, pass the list of
                                      // contexts down to the include parser, otherwise pass a null in
                                      _generatorConfig.GenerateIncludedCode ? contexts : null,
                                      parsedUris,
                                      parentDocuments,
                                      typeRegistry);
                    }
                }
            }
            finally
            {
                // Done parsing this document's includes, remove it from the parent chain
                parentDocuments.Pop();
            }

            // Make a note that we've already passed this document
            if (!parsedUris.Contains(uri))
            {
                CreateTypeVisitor(context.CodeNamespace, context).Visit(document);
                parsedUris.Add(uri);
                contexts.Add(context);
            }
            return(contexts);
        }
Esempio n. 2
0
 protected abstract DocumentContext CreateDocumentContext(Uri uri, string idlNamespace, GeneratorConfig config,
                                                          TypeRegistry typeRegistry);
Esempio n. 3
0
        private void ParseDocument(Uri uri,
                                   IDictionary <string, DocumentContext> contexts,
                                   TypeRegistry typeRegistry)
        {
            if (uri == null || !uri.IsAbsoluteUri)
            {
                throw new ArgumentException("Only absolute URIs can be parsed!");
            }
            if (_parentDocuments.Contains(uri))
            {
                throw new ArgumentException(string.Format("Input {0} recursively includes itself ({1})", uri,
                                                          string.Join(" -> ", _parentDocuments) + " -> " + uri));
            }

            if (_parsedDocuments.Contains(uri))
            {
                LOG.Debug(string.Format("Skipping already parsed file {0}...", uri));
                return;
            }

            LOG.Debug(string.Format("Parsing {0}...", uri));

            var idlNamespace = ExtractNamespace(uri);

            if (string.IsNullOrWhiteSpace(idlNamespace))
            {
                throw new ArgumentException(string.Format("URI {0} can not be translated to a namespace", uri));
            }

            var context = CreateDocumentContext(uri, idlNamespace, _generatorConfig, typeRegistry);

            var document = context.Document;
            var header   = document.Header;

            var codeNamespace = context.CodeNamespace;

            // Make a note that this document is a parent of all the documents included, directly or recursively
            _parentDocuments.Push(uri);

            try
            {
                if (header != null)
                {
                    foreach (var include in header.Includes)
                    {
                        Uri includeUri;
                        Uri.TryCreate(_generatorConfig.InputBase, include, out includeUri);
                        ParseDocument(includeUri,
                                      // If the includes should also generate code, pass the list of
                                      // contexts down to the include parser, otherwise pass a null in
                                      _generatorConfig.GenerateIncludedCode ? contexts : null,
                                      typeRegistry);
                    }
                }
            }
            finally
            {
                // Done parsing this document's includes, remove it from the parent chain
                _parentDocuments.Pop();
            }

            // Make a note that we've already passed this document
            _parsedDocuments.Add(uri);

            new TypeVisitor(codeNamespace, context).Visit(document);

            if (contexts != null)
            {
                if (contexts.ContainsKey(context.Namespace))
                {
                    LOG.Info(string.Format("Namespace {0} included multiple times!", context.Namespace));
                }
                contexts[context.Namespace] = context;
            }
        }