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); }
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)); } } } }
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"); }
//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); //} } }); }
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; } }