/// <summary>
        /// Exports the specified component to a temporary file, loads, and then parses the exported file.
        /// </summary>
        /// <param name="component"></param>
        public IDictionary <Tuple <string, DeclarationType>, Attributes> Parse(VBComponent component)
        {
            var path = _exporter.Export(component);

            if (!File.Exists(path))
            {
                // a document component without any code wouldn't be exported (file would be empty anyway).
                return(new Dictionary <Tuple <string, DeclarationType>, Attributes>());
            }
            var code = File.ReadAllText(path);

            File.Delete(path);
            var type = component.Type == vbext_ComponentType.vbext_ct_StdModule
                ? DeclarationType.ProceduralModule
                : DeclarationType.ClassModule;
            var preprocessor = _preprocessorFactory();
            var preprocessed = preprocessor.Execute(component.Name, code);
            var listener     = new AttributeListener(Tuple.Create(component.Name, type));
            // parse tree isn't usable for declarations because
            // line numbers are offset due to module header and attributes
            // (these don't show up in the VBE, that's why we're parsing an exported file)
            ITokenStream tokenStream;

            new VBAModuleParser().Parse(component.Name, preprocessed, new IParseTreeListener[] { listener }, out tokenStream);
            return(listener.Attributes);
        }
Beispiel #2
0
        /// <summary>
        /// Exports the specified component to a temporary file, loads, and then parses the exported file.
        /// </summary>
        /// <param name="component"></param>
        public IDictionary <Tuple <string, DeclarationType>, Attributes> Parse(VBComponent component)
        {
            var path = _exporter.Export(component);

            if (!File.Exists(path))
            {
                // a document component without any code wouldn't be exported (file would be empty anyway).
                return(new Dictionary <Tuple <string, DeclarationType>, Attributes>());
            }

            var code = File.ReadAllText(path);

            File.Delete(path);

            var type = component.Type == vbext_ComponentType.vbext_ct_StdModule
                ? DeclarationType.ProceduralModule
                : DeclarationType.ClassModule;
            var listener = new AttributeListener(Tuple.Create(component.Name, type));

            var stream = new AntlrInputStream(code);
            var lexer  = new VBALexer(stream);
            var tokens = new CommonTokenStream(lexer);
            var parser = new VBAParser(tokens);

            // parse tree isn't usable for declarations because
            // line numbers are offset due to module header and attributes
            // (these don't show up in the VBE, that's why we're parsing an exported file)
            var tree = parser.startRule();

            ParseTreeWalker.Default.Walk(listener, tree);

            return(listener.Attributes);
        }
Beispiel #3
0
        /// <summary>
        /// Exports the specified component to a temporary file, loads, and then parses the exported file.
        /// </summary>
        /// <param name="module"></param>
        /// <param name="cancellationToken"></param>
        public (IParseTree tree, ITokenStream tokenStream, IDictionary <Tuple <string, DeclarationType>, Attributes> attributes) Parse(QualifiedModuleName module, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var path = _exporter.Export(_projectsProvider.Component(module));

            if (!File.Exists(path))
            {
                // a document component without any code wouldn't be exported (file would be empty anyway).
                return(null, null, new Dictionary <Tuple <string, DeclarationType>, Attributes>());
            }

            string code;

            if (module.ComponentType == ComponentType.Document)
            {
                code = File.ReadAllText(path, Encoding.UTF8);   //We export the code from Documents as UTF8.
            }
            else
            {
                code = File.ReadAllText(path, Encoding.Default);    //The VBE exports encoded in the current ANSI codepage from the windows settings.
            }

            try
            {
                File.Delete(path);
            }
            catch
            {
                // Meh.
            }

            cancellationToken.ThrowIfCancellationRequested();

            var type = module.ComponentType == ComponentType.StandardModule
                ? DeclarationType.ProceduralModule
                : DeclarationType.ClassModule;
            var tokenStreamProvider = new SimpleVBAModuleTokenStreamProvider();
            var tokens       = tokenStreamProvider.Tokens(code);
            var preprocessor = _preprocessorFactory();
            var preprocessorErrorListener = new PreprocessorExceptionErrorListener(module.ComponentName, ParsePass.AttributesPass);

            preprocessor.PreprocessTokenStream(module.ComponentName, tokens, preprocessorErrorListener, cancellationToken);
            var listener = new AttributeListener(Tuple.Create(module.ComponentName, type));
            // parse tree isn't usable for declarations because
            // line numbers are offset due to module header and attributes
            // (these don't show up in the VBE, that's why we're parsing an exported file)

            var mainParseErrorListener = new MainParseExceptionErrorListener(module.ComponentName, ParsePass.AttributesPass);
            var parseResults           = new VBAModuleParser().Parse(module.ComponentName, tokens, new IParseTreeListener[] { listener }, mainParseErrorListener);

            cancellationToken.ThrowIfCancellationRequested();
            return(parseResults.tree, parseResults.tokenStream, listener.Attributes);
        }
Beispiel #4
0
        /// <summary>
        /// Exports the specified component to a temporary file, loads, and then parses the exported file.
        /// </summary>
        /// <param name="component"></param>
        /// <param name="token"></param>
        /// <param name="stream"></param>
        public IDictionary <Tuple <string, DeclarationType>, Attributes> Parse(IVBComponent component, CancellationToken token, out ITokenStream stream, out IParseTree tree)
        {
            token.ThrowIfCancellationRequested();
            var path = _exporter.Export(component);

            if (!File.Exists(path))
            {
                // a document component without any code wouldn't be exported (file would be empty anyway).
                stream = null;
                tree   = null;
                return(new Dictionary <Tuple <string, DeclarationType>, Attributes>());
            }
            var code = File.ReadAllText(path);

            try
            {
                File.Delete(path);
            }
            catch
            {
                // Meh.
            }

            token.ThrowIfCancellationRequested();

            var type = component.Type == ComponentType.StandardModule
                ? DeclarationType.ProceduralModule
                : DeclarationType.ClassModule;
            var tokenStreamProvider = new SimpleVBAModuleTokenStreamProvider();
            var tokens       = tokenStreamProvider.Tokens(code);
            var preprocessor = _preprocessorFactory();

            preprocessor.PreprocessTokenStream(component.Name, tokens, token);
            var listener = new AttributeListener(Tuple.Create(component.Name, type));

            // parse tree isn't usable for declarations because
            // line numbers are offset due to module header and attributes
            // (these don't show up in the VBE, that's why we're parsing an exported file)

            tree = new VBAModuleParser().Parse(component.Name, tokens, new IParseTreeListener[] { listener }, new ExceptionErrorListener(), out stream);

            token.ThrowIfCancellationRequested();
            return(listener.Attributes);
        }