public static string MultilineCloseReplacement(Match m) { if (m is null) { throw new ArgumentNullException(nameof(m)); } string x = m.ToString(); if (!x.Contains(",")) { return(x); } x = x.Trim(); var parts = x.split(@"\s+", 2); var parts2 = parts[1].split(","); string join = Translator.NewLine; foreach (var part in parts2) { join += parts[0].Trim() + " " + part.Trim() + Translator.NewLine; } DebugClass.LogError("CLOSE: " + m.toString() + ", JOIN: " + join); return(join); //return x.ToUpper(); }
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 Compile(IEnumerable <string> Files) { foreach (var fname in Files) { DebugClass.LogStandard("Parsing file: " + fname); var compileResult = VB6Compiler.Compile(fname); DebugClass.LogStandard(compileResult.CSharpCode); } }
public bool DoTokensMatch(Func <ParseTree, List <ParseTree> > GetChildren, ParseTree tree, bool justCheck = false) { if (GetChildren == null) { throw new ArgumentNullException(nameof(GetChildren)); } if (tree == null) { throw new ArgumentNullException(nameof(tree)); } // TODO: Doesn't handle recursion yet. /* * var testPattern = ".*" + string.Join(".*", PatternTokens) + ".*"; * var rex = Regex.IsMatch(tree.getText(), testPattern); * DebugClass.Log("TOKENMATCHING: " + tree.getText() + " against " + testPattern + " match? " + rex); * return rex; */ bool returnValue = true; foreach (var tokenInfo in PatternTokens) { if (finalCutDepthOfContent > tokenInfo.Path.Count) { // In this case the tokens were part of the template, not the pattern so we should skip them. continue; } var tokenCutPath = tokenInfo.Path.Skip(finalCutDepthOfContent).ToList(); var node = LookupNodeFromPath(GetChildren, tree, tokenCutPath, justCheck); if (node == null) { DebugClass.LogError("UNMATCHED TOKENS 1: " + VbTreeNodeType + ":" + PrintPath(tokenCutPath) + ":" + PrintPath(tokenInfo.Path)); returnValue = false; break; } var tokens = GetTokens(node); var tokenStrings = tokens.Select(x => x.Item2).ToList(); if (!tokenInfo.Tokens.SequenceEqual(tokenStrings)) { DebugClass.LogError("UNMATCHED TOKENS 2: " + VbTreeNodeType + ":" + PrintPath(tokenCutPath) + ":" + PrintPath(tokenInfo.Path)); DebugClass.LogError("PATH LENGTH COMPARISON: " + finalCutDepthOfContent + ":" + tokenInfo.Path.Count); DebugClass.LogError(string.Join("@", tokenInfo.Tokens)); DebugClass.LogError(string.Join("@", tokenStrings)); //return false; returnValue = false; } } return(returnValue); }
public ExpressionSyntax GetFirstGoodChild(string forwardType, ParseTree tree) { DebugClass.LogError("GetFirstGoodChild: " + forwardType); var list = GetGoodChildren(tree); if (list.Count > 1) { throw new InvalidOperationException("More than one good child."); } else if (list.Count > 0) { return(list[0]); } return(null); }
private static ParseTree LookupNodeFromPath(Func <ParseTree, List <ParseTree> > GetChildren, ParseTree root, List <IndexedPath> path, bool justCheck = false) { var node = root; foreach (var indexedPath in path) { //var child = node.getChild(indexedPath.ChildIndex); var children = GetChildren(node); if (!(indexedPath.ChildIndex >= 0 && indexedPath.ChildIndex < children.Count)) { DebugClass.LogError("Did not find child: " + PrintPath(path) + " in " + root.getText()); if (justCheck) { return(null); } throw new InvalidOperationException("child outside bounds"); } var child = children[indexedPath.ChildIndex]; var last = indexedPath == path[path.Count - 1]; if (!last && LookupNodeType(child) != indexedPath.NodeTypeName) { if (justCheck) { return(null); } throw new InvalidOperationException("child type doesn't match"); } node = child; } if (node == null) { if (justCheck) { return(null); } throw new InvalidOperationException(nameof(node) + " was null"); } return(node); }
private static void DebugDumpCSharpSyntax(SyntaxNode tree) { if (tree == null) { throw new ArgumentNullException(nameof(tree)); } var callback = new CsharpVisitorCallback() { Callback = node => { DebugClass.LogError("Node: " + node.Kind() + ": " + node.ToFullString()); } }; var walker = new CustomCSharpSyntaxWalker(callback); walker.Visit(tree); }
// This method looks up the depth of the $CONTENT identifier. // We use it to determine where to cut relative paths. // TODO: Parse wrapper only once, not one time per pattern. Well, it hardly matters for performance I think, so leave it. public void SetCutDepthAndCutPath() { var wrapperCompileResult = VB6Compiler.Compile("Test.bas", vbWrapperCode, false); var translator = new Translator(wrapperCompileResult); DebugClass.LogError("SetCutDepthAndCutPath: " + vbWrapperCode); var visitorCallback = new VisitorCallback() { Callback = (node, parent) => { var identifier = node.getText().Trim('"').Trim(); //if (identifier == Content) var path = translator.GetExtendedPathList(node); DebugClass.LogError("SetCutDepthAndCutPath: " + VbCode + ": " + PrintPath(path)); if (identifier == Content) { // Exact match if (path[path.Count - 1].NodeTypeName == "VsICSContext") { cutDepthOfContent = path.Count - 1; DebugClass.LogError("SetCutDepth: MATCH"); } // Bounded if (!PathContains(path, "VsICSContext")) { cutDepthOfContent = path.Count; DebugClass.LogError("SetCutDepth: BOUND MATCH"); } cutPath = path.Take(cutDepthOfContent).ToList(); } } }; // First time is to set cutDepthOfContent VB6Compiler.Visit(wrapperCompileResult, visitorCallback); // Second time is to set cutPath VB6Compiler.Visit(wrapperCompileResult, visitorCallback); if (cutDepthOfContent == -1) { throw new InvalidOperationException(nameof(cutDepthOfContent) + " not initialized"); } }
public static ExpressionSyntax TranslateExpression(Translator translator, ParseTree tree) { var result = Translate(translator, tree); DebugClass.LogError("Result: " + result); if (result is ExpressionSyntax es) { return(es); } else if (result is ExpressionStatementSyntax ess) { return(ess.Expression); } else { throw new InvalidOperationException("This shouldn't happen."); } }
void PopulateGrid() { DataTable grdPatternsDataSource = new DataTable("Patterns"); DataColumn c0 = new DataColumn("Node Type"); DataColumn c1 = new DataColumn("Context"); DataColumn c2 = new DataColumn("VB6 Pattern"); DataColumn c3 = new DataColumn("C# Replacement"); DataColumn c4 = new DataColumn("Matches#"); grdPatternsDataSource.Columns.Add(c0); grdPatternsDataSource.Columns.Add(c1); grdPatternsDataSource.Columns.Add(c2); grdPatternsDataSource.Columns.Add(c3); grdPatternsDataSource.Columns.Add(c4); foreach (var patternText in TranslatorForPattern.TranslatorPatterns) { DataRow row = grdPatternsDataSource.NewRow(); string nodeTypeName = "COMPILATION_ERROR"; int matchCount = 0; try { var pattern = patternText.Compile(); nodeTypeName = pattern.VbTreeNodeType; matchCount = GetMatches(pattern); } catch (VbParserException e) { DebugClass.LogError("Pattern Compile Failed: " + patternText.LogValue() + ": " + e.toString()); throw; } row["Node Type"] = nodeTypeName; row["Context"] = patternText.VbWrapperCode; row["VB6 Pattern"] = patternText.VbCode; row["C# Replacement"] = patternText.VbCode; row["Matches#"] = matchCount; grdPatternsDataSource.Rows.Add(row); } grdPatterns.DataSource = grdPatternsDataSource; }
static void Main(string[] args) { Console.Error.WriteLine("Use -g option to start GUI, or --help to show help for command line."); Parser.Default.ParseArguments <CommandLineOptions>(args) .WithParsed <CommandLineOptions>(o => { DebugClass.Init(); if (o.Verbose || o.GUI) { DebugClass.Enabled = true; } if (o.Compile || o.GUI) { TranslatorForPattern.IntializeTranslatorForPattern(); } if (o.Compile) { //DebugClass.LogStandard("") DebugClass.LogStandard("Compile"); if (o.Files == null) { DebugClass.LogStandard("No files specified!"); } else { Compile(o.Files); } } if (o.GUI) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var frm = new frmCompiler(); Application.Run(frm); frm.Dispose(); } }); }
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 string TranslatePropertyName(string ctrlType, string propertyName) { // TODO: Add control specific property mappings. // Actually it's probably so few that needs to be per control that // I can just put them in this method with a switch. if (vbToCSharpPropertyMapping.ContainsKey(propertyName)) { return(vbToCSharpPropertyMapping[propertyName]); } if (!seenProperties.ContainsKey(propertyName)) { DebugClass.LogError("// Control: " + ctrlType); DebugClass.LogError(String.Format(System.Globalization.CultureInfo.InvariantCulture, "{{\"{0}\", \"{0}\"}},", propertyName)); seenProperties[propertyName] = true; } //throw new System.NotImplementedException("Did not find property name in translatable properties."); return(propertyName); }
public VbToCsharpPattern(string vbWrapperCode, string vbCode, string csharpString) { this.vbWrapperCode = vbWrapperCode; this.VbCode = vbCode; this.csharpString = csharpString; VbParsePattern(vbCode); //CsharpParsedPattern = CSharpParsePattern(csharpString); DebugClass.LogError("ASGType: " + VbTreeNodeType); foreach (var path in VbPaths) { DebugClass.LogError("Path: " + PrintPath(path)); } /* * foreach (var path in CSharpPaths) * { * DebugClass.Log("Path: " + PrintPath(path)); * } */ }
public StatementSyntax TranslateProperty( string ctrlType, string ctrlIdentifier, VisualBasic6Parser.Cp_SinglePropertyContext property ) { var propertyName = vb6NodeTree .GetChildren(property) .Find(x => x is VisualBasic6Parser.ImplicitCallStmt_InStmtContext) .getText() .Trim(); var propertyValueContext = vb6NodeTree .GetChildren(property) .Find(x => x is VisualBasic6Parser.Cp_PropertyValueContext); var literalContext = vb6NodeTree .GetChildren(propertyValueContext) .Find(x => x is VisualBasic6Parser.LiteralContext); var asg = (LiteralImpl)_compileResult.Program.getASGElementRegistry().getASGElement(literalContext); if (asg == null) { DebugClass.LogError("ASG missing for: " + ctrlIdentifier + " for property: " + propertyName); throw new System.NotImplementedException("Don't know how to handle ASG null."); } var valueNode = TranslatorForExpression.GetExpression(asg); var valueString = valueNode.NormalizeWhitespace().ToFullString(); var translatedPropertyName = TranslatePropertyName(ctrlType, propertyName); return(SyntaxFactory.ParseStatement(ctrlIdentifier + "." + translatedPropertyName + " = " + valueString + ";")); }
public string[] GetIdentifiersAndSetTokens(Translator translator, CompileResult compileResult) { var identifiers = new List <string>(); var tokensPerNode = new List <TokenInfo>(); //var tokens = new List<Tuple<int, string>>(); var seen = new Dictionary <string, bool>(); var visitorCallback = new VisitorCallback() { Callback = (node, parent) => { //if (node.GetType().Name == "AmbiguousIdentifierContext") var identifier = node.getText().Trim('"').Trim(); //DebugClass.Log("GetIdentifier: " + identifier); var path = translator.GetExtendedPathList(node); if (IsInsideSubOrFunction(path)) { if (identifier.Length == 1 && identifier.All(char.IsUpper)) { if (!seen.ContainsKey(identifier)) { seen[identifier] = true; if (identifier != ReservedLetterForDiscardedResults) { identifiers.Add(identifier); } } } else { // A general method will for each token add the parent node, and its path, // then extract this path for each token, extract all tokens from path and // check that the token exists in the extracted tokens. // Does this account for the order? Partly, it accounts for the order // within different nodes, but not multiple tokens within the same node. // So to handle that we need to group tokens by node. var tokens = GetTokens(node); if (tokens.Count > 0) { tokenPath = tokenPath ?? path; tokensPerNode.Add(new TokenInfo(path, tokens.Select(x => x.Item2).ToList())); DebugClass.LogError("TOKENS" + string.Join("@", tokens)); } } } } }; VB6Compiler.Visit(compileResult, visitorCallback); _patternTokens = tokensPerNode; if (cutDepthOfContent == -1) { throw new InvalidOperationException(nameof(cutDepthOfContent) + " not initialized"); } return(identifiers.ToArray()); }
public void AppendExtra(string name, string extra) { DebugClass.LogError(extra); AddExtraModule?.Invoke(name, extra); }
public void VbParsePattern(string pattern) { SetCutDepthAndCutPath(); var code = vbWrapperCode.Replace(Content, pattern); var compileResult = VB6Compiler.Compile("Test.bas", code, false); var translator = new Translator(compileResult); PatternIdentifiers = GetIdentifiersAndSetTokens(translator, compileResult); var paths = new List <IndexedPath> [PatternIdentifiers.Length]; ParseTree root = null; DebugClass.LogError("PATTERN: " + VbCode); var visitorCallback = new VisitorCallback() { Callback = (node, parent) => { DebugClass.LogError("Node: " + PrintPath(translator.GetExtendedPathList(node)) + ": " + node.getText()); if (root == null) { root = node; } var i = 0; foreach (var identifier in PatternIdentifiers) { if (node.getText().Trim('"') == identifier && IsInsideSubOrFunction(translator.GetExtendedPathList(node))) { var path = translator.GetExtendedPathList(node); if (paths[i] == null) { paths[i] = path; } } i++; } } }; VB6Compiler.Visit(compileResult, visitorCallback); var lowestCommonDepth = -1; var cutDepth = -1; var comparePath = paths.Length > 0 ? paths[0] : tokenPath; if (comparePath == null) { DebugClass.LogError("VB Code: " + VbCode); throw new InvalidOperationException(nameof(comparePath) + " is null"); } int commonDepth = Math.Min(cutPath.Count, comparePath.Count); for (int i = 0; i < commonDepth; i++) { DebugClass.LogError("COMPARE PATHS: " + PrintPath(cutPath)); foreach (var path in paths) { DebugClass.LogError("COMPARE PATHS: " + PrintPath(path)); } DebugClass.LogError(""); if (cutPath[i].NodeTypeName != comparePath[i].NodeTypeName) { break; } else { lowestCommonDepth = Math.Min(comparePath.Count - 1, i + 1); } } if (lowestCommonDepth >= comparePath.Count) { DebugClass.LogError("VB Code: " + VbCode + ", Identifier: " + PatternIdentifiers[0]); } VbTreeNodeType = comparePath[lowestCommonDepth].NodeTypeName; // Skip uninteresting wrapper nodes while (VbTreeNodeType == "VsICSContext" || VbTreeNodeType == "ImplicitCallStmt_InStmtContext") { lowestCommonDepth++; VbTreeNodeType = comparePath[lowestCommonDepth].NodeTypeName; } // VbTreeNodeType == "ICS_B_ProcedureCallContext") while (VbTreeNodeType == "ArgsCallContext" || VbTreeNodeType == "AmbiguousIdentifierContext") { lowestCommonDepth--; VbTreeNodeType = comparePath[lowestCommonDepth].NodeTypeName; } cutDepth = lowestCommonDepth + 1; finalCutDepthOfContent = cutDepth; var cutPaths = new List <IndexedPath> [PatternIdentifiers.Length]; var k = 0; foreach (var path in paths) { var cutPath = new List <IndexedPath>(); for (var i = cutDepth; i < path.Count; i++) { cutPath.Add(path[i]); } cutPaths[k] = cutPath; k++; } VbPaths = cutPaths; }
public SyntaxNode Translate(Translator translator, ParseTree tree) { if (translator == null) { throw new ArgumentNullException(nameof(translator)); } if (tree == null) { throw new ArgumentNullException(nameof(tree)); } if (!DoTokensMatch(translator.GetChildren, tree)) { throw new InvalidOperationException("Missing tokens. Fix CanTranslate."); } var replacement = csharpString; // Make a long string so we don't conflict foreach (var identifier in PatternIdentifiers) { replacement = Regex.Replace(replacement, "\\b" + identifier + "\\b", GetUniqueIdentifier(identifier)); } var pathIndex = 0; foreach (var identifier in PatternIdentifiers) { var path = VbPaths[pathIndex]; var node = LookupNodeFromPath(translator.GetChildren, tree, path); DebugClass.LogError( "Extracting Identifier: " + identifier + " with path " + PrintPath(path) + " for code " + tree.getText()); var translated = translator.TranslateNode(node); var uid = GetUniqueIdentifier(identifier); if (translated != null) { DebugDumpCSharpSyntax(translated); DebugClass.LogError("Extracted: " + translated.NormalizeWhitespace().ToFullString()); replacement = replacement.replace(uid, translated.NormalizeWhitespace().ToFullString()); } else { DebugClass.LogError("UNTRANSLATED_ " + LookupNodeType(node) + ", ASG: " + translator.GetAsg <ASGElement>(node)?.GetType()?.Name + ", Identifier: " + identifier + ", Path: " + PrintPath(path) + "(" + node.getText().Trim() + ")"); replacement = replacement.replace( uid, "throw new NotImplementedException(\"UNTRANSLATED: " + LookupNodeType(node) + ":" + node.getText().Trim() + "\");"); } //translations[i] = translated; pathIndex++; } SyntaxNode rewritten; if (Translator.IsStatement(tree)) { rewritten = SyntaxFactory.ParseStatement(replacement); } else { rewritten = SyntaxFactory.ParseExpression(replacement); } return(rewritten.NormalizeWhitespace()); }
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 ProcessProperties( string ctrlType, ParseTree node, List <StatementSyntax> statements, string ctrlIdentifier) { if (node is null) { throw new ArgumentNullException(nameof(node)); } if (statements is null) { throw new ArgumentNullException(nameof(statements)); } if (ctrlIdentifier is null) { throw new ArgumentNullException(nameof(ctrlIdentifier)); } foreach (var child in vb6NodeTree.GetChildren(node)) { if (child is VisualBasic6Parser.Cp_PropertiesContext) { // This is one of the properties var simpleProperty = vb6NodeTree.GetChildren(child).Find(x => x is VisualBasic6Parser.Cp_SinglePropertyContext); var nestedControlProperty = vb6NodeTree.GetChildren(child).Find(x => x is VisualBasic6Parser.ControlPropertiesContext); var nestedProperty = vb6NodeTree.GetChildren(child).Find(x => x is VisualBasic6Parser.Cp_NestedPropertyContext); if (simpleProperty != null) { statements.Add( TranslateProperty( ctrlType, ctrlIdentifier, (VisualBasic6Parser.Cp_SinglePropertyContext)simpleProperty)); } else if (nestedControlProperty != null) { statements.AddRange(TranslateControl( (VisualBasic6Parser.ControlPropertiesContext)nestedControlProperty)); var nestedControlName = GetNameOfControl((VisualBasic6Parser.ControlPropertiesContext)nestedControlProperty); var statementString = ctrlIdentifier + ".Controls.Add(" + nestedControlName + ");"; var assignPropertyStatement = SyntaxFactory.ParseStatement(statementString); statements.Add(assignPropertyStatement); } else if (nestedProperty != null) { var nestedName = vb6NodeTree.GetChildren(nestedProperty) .Find(x => x is VisualBasic6Parser.AmbiguousIdentifierContext || x is VisualBasic6Parser.CertainIdentifierContext).getText().trim(); var translatedNestedName = TranslatePropertyName(ctrlType, nestedName); ProcessProperties(translatedNestedName, nestedProperty, statements, ctrlIdentifier + "." + nestedName); } else { foreach (var grandchild in vb6NodeTree.GetChildren(child)) { DebugClass.LogError("GRANDCHILD: " + grandchild.GetType().Name + " " + grandchild.getText()); } throw new System.NotImplementedException("Property not handled for: " + ctrlIdentifier); } } } }
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; } }