/* Function: FromPlainText * * Creates a SymbolString from the passed string of plain text. * * If the string ends in parameters they will be separated off from the string and returned in the parameters variable. They will * not be part of the resulting SymbolString. The string is still in its raw form so to become a <ParameterString> it would need * to be passed to <ParameterString.FromPlainText()>. If there's no parameters the variable will be null. * * The string will be normalized. If you know the string is already in a normalized form because it originally came * from another SymbolString object, use <FromExportedString()>. */ static public SymbolString FromPlainText(string textSymbol, out string parameters) { if (textSymbol == null) { throw new NullReferenceException(); } string undecoratedTextSymbol; ParameterString.SplitFromParameters(textSymbol, out undecoratedTextSymbol, out parameters); SymbolString symbolString = new SymbolString(undecoratedTextSymbol); symbolString.Normalize(); // If a symbol string is normalized to nothing yet it had parentheses (think "::()") put them back together and redo. // This should be a rare edge case but we want to handle it. We never want a null symbol string with a valid // parentheses string. if (symbolString.symbolString == null && parameters != null) { symbolString = new SymbolString(textSymbol); symbolString.Normalize(); parameters = null; } return(symbolString); }
/* Function: FromPlainText_NoParameters * * Creates a SymbolString from the passed string of plain text which is guaranteed to not have parameters or has already had * them removed. * * We use this awkward function name because much of the time you need to handle parameters, or at least strip them * off. If we just made an overload of <FromPlainText()> without the out parameter people would use this one by accident. * By attaching _NoParameters it forces you to only use this one if you know what you're doing. * * The string will be normalized. If you know the string is already in a normalized form because it originally came * from another SymbolString object, use <FromExportedString()>. */ static public SymbolString FromPlainText_NoParameters(string textSymbol) { if (textSymbol == null) { throw new NullReferenceException(); } SymbolString symbolString = new SymbolString(textSymbol); symbolString.Normalize(); return(symbolString); }
/* Function: FromParameters * Creates a UsingString from the passed parameters. */ static public UsingString FromParameters(UsingType type, SymbolString prefixToAdd, SymbolString prefixToRemove = default(SymbolString)) { StringBuilder stringBuilder = new System.Text.StringBuilder(prefixToAdd.ToString().Length + 1); if (type == UsingType.AddPrefix) { stringBuilder.Append('A'); if (prefixToAdd == null) { throw new InvalidOperationException(); } stringBuilder.Append(prefixToAdd.ToString()); } else if (type == UsingType.ReplacePrefix) { stringBuilder.Append('R'); if (prefixToAdd == null || prefixToRemove == null) { throw new InvalidOperationException(); } stringBuilder.Append(prefixToRemove); stringBuilder.Append(SeparatorChar); stringBuilder.Append(prefixToAdd); } else { throw new InvalidOperationException(); } return(new UsingString(stringBuilder.ToString())); }
/* Function: CompareTo */ public int CompareTo(SymbolString other, bool ignoreCase = false) { return(string.Compare(symbolString, other.symbolString, ignoreCase)); }
/* Function: EndsWith * Returns whether the end of the symbol matches the passed symbol, such as "PackageA.PackageB.Function" and "PackageB.Function". * It must match a complete segment, so "PackageA.PackageB.Function" will not match "B.Function". */ public bool EndsWith(SymbolString other, bool ignoreCase = false) { return(symbolString.Length > other.symbolString.Length && symbolString[symbolString.Length - other.symbolString.Length - 1] == SeparatorChar && symbolString.EndsWith(other.symbolString, (ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))); }
/* Function: FromParameters * Creates a ClassString from the passed parameters. */ static public ClassString FromParameters(HierarchyType hierarchy, int languageID, bool caseSensitive, SymbolString symbol) { if (symbol == null) { throw new NullReferenceException(); } // SymbolString plus hierarchy, language ID, and separator. It's almost definitely only going to use one char for the // language ID, but getting room for a second one just to be certain isn't a big deal when we're already paying for the // allocation. StringBuilder stringBuilder = new System.Text.StringBuilder(symbol.ToString().Length + 4); if (hierarchy == HierarchyType.Class) { if (caseSensitive) { stringBuilder.Append('C'); } else { stringBuilder.Append('c'); } } else // (hierarchy == HierarchyType.Database) { if (caseSensitive) { stringBuilder.Append('D'); } else { stringBuilder.Append('d'); } } do { int value = languageID & 0x0000003F; if (value < 10) { stringBuilder.Append((char)('0' + value)); } else if (value < 36) { stringBuilder.Append((char)('A' + (value - 10))); } else if (value < 62) { stringBuilder.Append((char)('a' + (value - 36))); } else if (value == 62) { stringBuilder.Append('!'); } else // (value == 63) { stringBuilder.Append('@'); } languageID >>= 6; }while (languageID > 0); stringBuilder.Append(SeparatorChar); string symbolString = symbol.ToString(); stringBuilder.Append(symbolString); string classString = stringBuilder.ToString(); string lookupKey; if (caseSensitive) { lookupKey = classString; } else { stringBuilder.Remove(stringBuilder.Length - symbolString.Length, symbolString.Length); stringBuilder.Append(symbolString.ToLower()); lookupKey = stringBuilder.ToString(); } return(new ClassString(classString, lookupKey)); }
/* Function: EndsWith * Returns whether the end of the symbol matches the passed symbol, such as "PackageA.PackageB.Function" and "PackageB.Function". * It must match a complete segment, so "PackageA.PackageB.Function" will not match "B.Function". */ public bool EndsWith(SymbolString other, bool ignoreCase = false) { return(symbolString.Length > other.symbolString.Length && symbolString[symbolString.Length - other.symbolString.Length - 1] == SeparatorChar && symbolString.EndsWith(other.symbolString, ignoreCase, System.Globalization.CultureInfo.CurrentCulture)); }