int GetMatches(VbToCsharpPattern pattern)
        {
            int matches = 0;

            foreach (var fileName in fileNames)
            {
                if (fileName.EndsWith(".frx", StringComparison.InvariantCulture))
                {
                    continue;
                }

                var compileResult = compileResults[fileName];
                var nodeTree      = new VB6NodeTree(compileResult);

                foreach (var node in nodeTree.GetAllNodes())
                {
                    if (pattern.CanTranslate(nodeTree.GetChildren, node))
                    {
                        matches++;
                    }
                }
            }

            return(matches);
        }
Beispiel #2
0
 public static bool IsStatement(ParseTree tree)
 {
     if (tree == null)
     {
         throw new ArgumentNullException(nameof(tree));
     }
     return(VbToCsharpPattern.LookupNodeType(tree).EndsWith("StmtContext", StringComparison.InvariantCulture));
 }
        public static bool CanTranslate(Translator translator, ParseTree tree)
        {
            if (tree == null)
            {
                throw new ArgumentNullException(nameof(tree));
            }
            if (translator == null)
            {
                throw new ArgumentNullException(nameof(translator));
            }
            var name = VbToCsharpPattern.LookupNodeType(tree);

            if (name == null)
            {
                throw new NullReferenceException(nameof(name));
            }
            if (compiledPatterns == null)
            {
                throw new NullReferenceException(nameof(compiledPatterns));
            }

            var canTranslate = compiledPatterns.ContainsKey(name);

            if (canTranslate)
            {
                canTranslate = false;
                foreach (var pattern in compiledPatterns[name])
                {
                    if (pattern.CanTranslate(translator.GetChildren, tree))
                    {
                        canTranslate = true;
                        break;
                    }
                    ;
                }

                if (!canTranslate)
                {
                    DebugClass.LogError("PATTERN NODE: " + name + ", CASE: " + tree.getText());
                    foreach (var pattern in compiledPatterns[name])
                    {
                        foreach (var tokens in pattern.PatternTokens)
                        {
                            DebugClass.LogError("TOKENS: " + string.Join("@", tokens.Tokens));
                        }
                    }

                    if (name != "ImplicitCallStmt_InBlockContext")
                    {
                        throw new InvalidOperationException("Valid patterns for case, but none of them worked.");
                    }
                }
            }
            return(canTranslate);
        }
        public static void CompileAll()
        {
            var patterns = TranslatorPatterns;

            compiledPatterns = new Dictionary <string, List <VbToCsharpPattern> >();
            foreach (var patternText in patterns)
            {
                VbToCsharpPattern pattern = null;
                try
                {
                    pattern = patternText.Compile();
                }
                catch (VbParserException e)
                {
                    DebugClass.LogError("Pattern Compile Failed: " + patternText.LogValue() + ": " + e.toString());
                    throw;
                }

                DebugClass.LogError(
                    "Pattern: " + patternText.LogValue() + ", " +
                    nameof(pattern.VbTreeNodeType) + ": " + pattern.VbTreeNodeType);

                if (!compiledPatterns.ContainsKey(pattern.VbTreeNodeType))
                {
                    compiledPatterns[pattern.VbTreeNodeType] = new List <VbToCsharpPattern>();
                }
                compiledPatterns[pattern.VbTreeNodeType].Add(pattern);
            }

            foreach (var pat in compiledPatterns)
            {
                foreach (var pat2 in pat.Value)
                {
                    DebugClass.LogError("PATTERNSTATUS: " + pat2.VbCode + ": " + pat2.VbTreeNodeType + ": " + pat2.GetLogPath());
                    foreach (var tki in pat2.PatternTokens)
                    {
                        DebugClass.LogError("PATTERNTOKENS: " + VbToCsharpPattern.PrintPath(tki.Path));
                        DebugClass.LogError("PATTERNTOKENS: " +
                                            string.Join("@", tki.Tokens));
                    }
                }
            }
        }
Beispiel #5
0
        public static List <IndexedPath> GetExtendedPathList(VB6NodeTree nodeTree, ParseTree node)
        {
            if (nodeTree == null)
            {
                throw new ArgumentNullException(nameof(nodeTree));
            }

            var iterationNode = node;
            var s             = new List <IndexedPath>();
            int depth         = 0;

            while (iterationNode != null)
            {
                var index = -1;
                if (iterationNode.getParent() != null)
                {
                    var i = 0;
                    foreach (var child in nodeTree.GetChildren(iterationNode.getParent()))
                    {
                        if (child == iterationNode)
                        {
                            index = i;
                            break;
                        }
                        i++;
                    }

                    if (index == -1)
                    {
                        throw new InvalidOperationException("could not find child node in parent");
                    }
                }
                s.Add(new IndexedPath(VbToCsharpPattern.LookupNodeType(iterationNode), index, iterationNode.getText()));
                iterationNode = iterationNode.getParent();
                depth++;
                if (depth > 100)
                {
                    throw new InvalidOperationException("depth too big");
                }
            }
            s.Reverse();
            return(s);
        }
        public static string GetNodeTreeHashString(VB6SubTree nodeTree)
        {
            if (nodeTree == null)
            {
                throw new ArgumentNullException(nameof(nodeTree));
            }

            var typeNames = new List <string>();
            var count     = 0;

            foreach (var node in nodeTree.GetAllNodes())
            {
                typeNames.Add(VbToCsharpPattern.LookupNodeType(node));
                count++;
                if (count > 20)
                {
                    break;
                }
            }
            return(String.Join("/", typeNames));
        }
        private void frmVB6ASTBrowser_Load(object sender, EventArgs e)
        {
            var compileResult = VB6Compiler.Compile(FileName, null, false);

            nodeMap = new Dictionary <ParseTree, TreeNode>();

            translator = new Translator(compileResult);

            var visitorCallback = new VisitorCallback()
            {
                Callback = (node, parent) =>
                {
                    var    name      = VbToCsharpPattern.LookupNodeType(node);
                    var    lines     = node.getText().Split('\n');
                    string firstLine = (lines.Length > 0) ? lines[0] : "";

                    if (parent != null && nodeMap.ContainsKey(parent))
                    {
                        var tvNode = nodeMap[parent].Nodes.Add(nodeMap.Count.ToString(new NumberFormatInfo()), name + ": " + firstLine);
                        tvNode.Tag    = node;
                        nodeMap[node] = tvNode;
                    }
                    else
                    {
                        var tvNode = treVB6AST.Nodes.Add(nodeMap.Count.ToString(new NumberFormatInfo()), name + ": " + firstLine);
                        tvNode.Tag    = node;
                        nodeMap[node] = tvNode;
                    }

                    //nodes.Add(node);
                }
            };

            txtDebug.ScrollBars = ScrollBars.Both;

            VB6Compiler.Visit(compileResult, visitorCallback);

            //treVB6AST.ExpandAll();
        }
        public static SyntaxNode Translate(Translator translator, ParseTree tree)
        {
            if (translator == null)
            {
                throw new ArgumentNullException(nameof(translator));
            }
            if (tree == null)
            {
                throw new ArgumentNullException(nameof(tree));
            }
            var name     = VbToCsharpPattern.LookupNodeType(tree);
            var patterns = compiledPatterns[name];

            foreach (var pattern in patterns)
            {
                if (pattern.CanTranslate(translator.GetChildren, tree))
                {
                    return(pattern.Translate(translator, tree));
                }
            }
            throw new InvalidOperationException("Should not happen if we call CanTranslate before Translate");
        }
Beispiel #9
0
        //private Dictionary<ParseTree, ImmutableList<int>> tokenIndices;

        public VisitorCallback Init()
        {
            children = new Dictionary <ParseTree, List <ParseTree> >();
            depths   = new Dictionary <ParseTree, int>();
            paths    = new Dictionary <ParseTree, ImmutableList <IndexedPath> >();
            //tokenIndices = new Dictionary<ParseTree, ImmutableList<int>>();

            return(new VisitorCallback()
            {
                Callback = (node, parent) =>
                {
                    // Just make sure all nodes, even leaves, have empty children lists
                    if (!children.ContainsKey(node))
                    {
                        children[node] = new List <ParseTree>();
                    }

                    // Add this to children of parent
                    if (!children.ContainsKey(node.getParent()))
                    {
                        children[node.getParent()] = new List <ParseTree>();
                    }
                    children[node.getParent()].Add(node);

                    // Depth updating
                    if (!depths.ContainsKey(node))
                    {
                        depths[node] = 0;
                    }

                    // Add this to children of parent
                    if (!depths.ContainsKey(node.getParent()))
                    {
                        depths[node.getParent()] = 0;
                    }
                    depths[node] = depths[node.getParent()] + 1;

                    // Path updating
                    if (!paths.ContainsKey(node))
                    {
                        paths[node] = ImmutableList.Create <IndexedPath>();
                    }

                    // Add this to children of parent
                    if (!paths.ContainsKey(node.getParent()))
                    {
                        paths[node.getParent()] = ImmutableList.Create <IndexedPath>();
                    }
                    int childIndex = children[node.getParent()].Count;
                    string token = new String(node.getText().Take(50).ToArray());
                    if (token.Length >= 50)
                    {
                        token += "...";
                    }
                    paths[node] = paths[node.getParent()].Add(new IndexedPath(VbToCsharpPattern.LookupNodeType(node), childIndex, token));



                    //for (int i = 0; i < node.getChildCount(); i++)
                    //{
                    //    node.getChild(i);
                    //}
                }
            });
        }
Beispiel #10
0
        public ExpressionSyntax GetExpression(ParseTree tree)
        {
            if (tree == null)
            {
                throw new ArgumentNullException(nameof(tree));
            }

            var asg = this.translator.Program.getASGElementRegistry().getASGElement(tree);

            if (TranslatorForPattern.CanTranslate(translator, tree))
            {
                return(TranslatorForPattern.TranslateExpression(this.translator, tree));
            }

            var goodChildren = GetGoodChildren(tree);

            if (goodChildren.Count == 1)
            {
                DebugClass.LogError("FORWARDED: " + VbToCsharpPattern.LookupNodeType(tree) + ": " + tree.getText());
                return(goodChildren[0]);
            }

            // TODO: optimize if too slow
            var methods = this.GetType().GetMethods();

            foreach (var method in methods)
            {
                if (method.Name.Equals("GetExpression", StringComparison.InvariantCulture))
                {
                    var methodParameters = method.GetParameters();

                    if (methodParameters.Length > 0 && asg != null && methodParameters[0].ParameterType == asg.GetType())
                    {
                        DebugClass.LogError("OBSOLETE: Invoking specific GetExpression on: " + tree.getText());
                        //statements.Add(SyntaxFactory.EmptyStatement().WithLeadingTrivia(SyntaxFactory.Comment("// Invoking GetExpression: " + asg.GetType().Name + ":" + asg.getCtx().depth())));
                        return((ExpressionSyntax)method.Invoke(this, new object[] { asg }));
                    }
                }
            }

            /*else if (tree is VisualBasic6Parser.TypeHintContext)
             * {
             *  return SyntaxFactory.CastExpression(
             *      SyntaxFactory.Token(SyntaxKind.OpenParenToken),
             *      SyntaxFactory.ParseTypeName("string"),
             *      SyntaxFactory.Token(SyntaxKind.CloseParenToken),
             *  );*/

            if (tree is TerminalNodeImpl)
            {
                return(null);
            }
            else if (tree is VisualBasic6Parser.CertainIdentifierContext ||
                     tree is VisualBasic6Parser.AmbiguousIdentifierContext ||
                     tree is VisualBasic6Parser.AmbiguousKeywordContext)
            {
                var name = tree.getText().Trim();
                if (!name.All(c => char.IsLetterOrDigit(c) || "_$".Contains(c)))
                {
                    throw new InvalidOperationException("Identifier was not alphanumeric: " + name);
                }
                return(SyntaxFactory.IdentifierName(name));
            }
            else if (tree is VisualBasic6Parser.ArgsCallContext)
            {
                return(GetFirstGoodChild(nameof(ConstantCallImpl), tree));
            }
            else if (tree is VisualBasic6Parser.BaseTypeContext btc)
            {
                return(HandleBaseTypeContext(btc));
            }
            else if (tree is VisualBasic6Parser.TypeHintContext)
            {
                // Ignore type hint context
                DebugClass.LogError("IGNORING TYPE HINT CONTEXT");
                return(null);
            }

            var explanation = "// " + VbToCsharpPattern.LookupNodeType(tree) + " not in [" + TranslatorForPattern.DocPatterns() + "]" + Translator.NewLine;

            DebugClass.LogError(nameof(GetExpression) + ": " + VbToCsharpPattern.LookupNodeType(tree) + ": " + tree.getText());
            DebugClass.LogError(explanation);
            if (asg != null)
            {
                DebugClass.LogError(nameof(GetExpression) + ": " + asg.GetType().Name);
            }
            // TODO: Reenable.
            throw new InvalidOperationException("Expression returned null");

            //return null;
        }
        public void GetPatterns(VB6NodeTree nodeTree)
        {
            if (nodeTree == null)
            {
                throw new ArgumentNullException(nameof(nodeTree));
            }

            // Iterate over all nodes and add them to node hash based on their concatenated type strings
            foreach (var node in nodeTree.GetAllNodes())
            {
                var subtree = new VB6SubTree(nodeTree, node);

                //var nodeTreeHashString = GetNodeTreeHashString(subtree);
                var nodeHash = GetNodeHash(node);

                if (!nodeHashDict.ContainsKey(nodeHash))
                {
                    nodeHashDict[nodeHash] = new Dictionary <string, List <VB6SubTree> >();
                }
                var tokens = String.Join(" ", GetTokens(node));
                if (!nodeHashDict[nodeHash].ContainsKey(tokens))
                {
                    nodeHashDict[nodeHash][tokens] = new List <VB6SubTree>();
                }
                nodeHashDict[nodeHash][tokens].Add(subtree);
            }

            foreach (var key in nodeHashDict.Keys)
            {
                foreach (var key2 in nodeHashDict[key].Keys)
                {
                    var s = new List <string>();
                    foreach (var subtree in nodeHashDict[key][key2])
                    {
                        var node   = subtree.GetRoot();
                        var tokens = String.Join(" ", GetTokens(node));
                        s.Add(tokens);
                    }
                    var s2 = String.Join(", ", s);
                    DebugClass.LogError("NodeTreeHashString: " + key + " " + key2 + ": " + nodeHashDict[key][key2].Count + ": " + s2);
                }
            }

            // TODO: Is it possible to auto-generate this dictionary?
            // No stress, it's small, but would be nice for other languages.
            var replaceable = new Dictionary <string, bool>();

            replaceable["AmbiguousIdentifierContext"] = true;
            replaceable["CertainIdentifierContext"]   = true;
            replaceable["LiteralContext"]             = true;
            replaceable["FieldLengthContext"]         = true;

            // Iterate over all nodes and replace each token/text in pattern with pattern letter,
            // if there are two or more variations of this token under this node type name
            const string letters = "ABCDEFGHIJKLMNOPQRSTUVXYZ";

            foreach (var node in nodeTree.GetAllNodes())
            {
                var subtree     = new VB6SubTree(nodeTree, node);
                int letterIndex = 0;
                var text        = node.getText();
                var pattern     = text;

                foreach (var child in subtree.GetAllNodes())
                {
                    if (replaceable.ContainsKey(VbToCsharpPattern.LookupNodeType(child)))
                    {
                        //DebugClass.LogError("REPLACING: " + VbToCsharpPattern.LookupNodeType(child));
                        var tokens = GetTokens(child);
                        foreach (var token in tokens)
                        {
                            if (letterIndex < letters.Length)
                            {
                                var oldPattern = pattern;
                                pattern = pattern.Replace(token, letters[letterIndex].ToString(System.Globalization.CultureInfo.InvariantCulture));
                                if (pattern != oldPattern)
                                {
                                    letterIndex++;
                                }
                                //DebugClass.LogError("REPLACING: " + token);
                            }

                            if (letterIndex >= letters.Length)
                            {
                                break;
                            }
                        }
                        if (letterIndex >= letters.Length)
                        {
                            break;
                        }
                    }
                }
                if (pattern.Length >= 100)
                {
                    pattern = "PATTERN TOO LONG";
                }
                generatedPatterns[node] = pattern;
            }
        }