public static bool IsValid(ref string expanded, SymbolDefinition context, FGGrammar.TokenSet expected) { var methodDef = context as MethodDefinition; var checkKeyword = false; for (var index = 0; (index = expanded.IndexOf('$', index)) != -1; ) { var end = expanded.IndexOf('$', index + 1); if (end < index) break; var macro = expanded.Substring(index + 1, end - index - 1); switch (macro) { case "MethodName": case "ArgumentList": if (methodDef == null) return false; break; case "ValidIfKeywordExpected": checkKeyword = true; expanded = expanded.Remove(index, end - index + 2); continue; case "ValidAsStatement": if (expected != null && !expected.Matches(CsGrammar.Instance.tokenStatement)) return false; expanded = expanded.Remove(index, end - index + 2); continue; case "NotValidAsStatement": if (expected != null && expected.Matches(CsGrammar.Instance.tokenStatement)) return false; expanded = expanded.Remove(index, end - index + 2); continue; case "ValidAsClassMember": if (expected != null && !expected.Matches(CsGrammar.Instance.tokenClassBody)) return false; expanded = expanded.Remove(index, end - index + 2); continue; case "ValidAsStructMember": if (expected != null && !expected.Matches(CsGrammar.Instance.tokenStructBody)) return false; expanded = expanded.Remove(index, end - index + 2); continue; case "ValidAsInterfaceMember": if (expected != null && !expected.Matches(CsGrammar.Instance.tokenInterfaceBody)) return false; expanded = expanded.Remove(index, end - index + 2); continue; case "ValidAsNamespaceMember": if (expected != null && !expected.Matches(CsGrammar.Instance.tokenNamespaceBody)) return false; expanded = expanded.Remove(index, end - index + 2); continue; case "ValidAsTypeDeclaration": if (expected != null && !( expected.Matches(CsGrammar.Instance.tokenNamespaceBody) || expected.Matches(CsGrammar.Instance.tokenClassBody) || expected.Matches(CsGrammar.Instance.tokenStructBody) )) return false; expanded = expanded.Remove(index, end - index + 2); continue; case "ValidInMethodBody": if (methodDef == null) return false; expanded = expanded.Remove(index, end - index + 2); continue; case "ValidInPropertyBody": if (context == null || context.kind != SymbolKind.Property && (context.parentSymbol == null || context.parentSymbol.kind != SymbolKind.Property)) return false; expanded = expanded.Remove(index, end - index + 2); continue; } index = end + 1; } if (checkKeyword && expected != null) { var index = 0; while (expanded[index] >= 'a' && expanded[index] <= 'z') ++index; if (index == 0) { if (expanded.StartsWith("!=", System.StringComparison.Ordinal) || expanded.StartsWith("==", System.StringComparison.Ordinal)) index = 2; else return false; } var keyword = expanded.Substring(0, index); var tokenId = CsGrammar.Instance.TokenToId(keyword); if (!expected.Matches(tokenId)) return false; } return true; }