private NativeImportRecord( ImportTargetKind targetKind, string externAlias, string alias, string targetString) { _targetKind = targetKind; _externAlias = externAlias; _alias = alias; _targetString = targetString; }
public ImportRecord( ImportTargetKind targetKind, string alias = null, ITypeSymbol targetType = null, string targetString = null, IAssemblySymbol targetAssembly = null, string targetAssemblyAlias = null) { TargetKind = targetKind; Alias = alias; TargetType = targetType; TargetString = targetString; TargetAssembly = targetAssembly; TargetAssemblyAlias = targetAssemblyAlias; }
/// <summary> /// Parse a string representing a VB import statement. /// </summary> /// <exception cref="ArgumentNullException"><paramref name="import"/> is null.</exception> /// <exception cref="ArgumentException">Format of <paramref name="import"/> is not valid.</exception> public static void ParseVisualBasicImportString(string import, out string alias, out string target, out ImportTargetKind kind, out ImportScope scope) { if (import == null) { throw new ArgumentNullException("import"); } if (import.Length == 0) // VB current namespace { alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return; } int pos = 0; switch (import[pos]) { case '*': // VB default namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.DefaultNamespace; scope = ImportScope.Unspecified; return; case '@': // VB cases other than default and current namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; if (pos >= import.Length) { throw new ArgumentException(import, "import"); } scope = ImportScope.Unspecified; switch (import[pos]) { case 'F': scope = ImportScope.File; pos++; break; case 'P': scope = ImportScope.Project; pos++; break; } if (pos >= import.Length) { throw new ArgumentException(import, "import"); } switch (import[pos]) { case 'A': pos++; if (import[pos] != ':') { throw new ArgumentException(import, "import"); } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { throw new ArgumentException(import, "import"); } kind = ImportTargetKind.NamespaceOrType; return; case 'X': pos++; if (import[pos] != ':') { throw new ArgumentException(import, "import"); } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { throw new ArgumentException(import, "import"); } kind = ImportTargetKind.XmlNamespace; return; case 'T': pos++; if (import[pos] != ':') { throw new ArgumentException(import, "import"); } pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Type; return; case ':': pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Namespace; return; default: alias = null; target = import.Substring(pos); kind = ImportTargetKind.MethodToken; return; } default: // VB current namespace alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return; } }
/// <summary> /// Parse a string representing a C# using (or extern alias) directive. /// </summary> /// <remarks> /// <![CDATA[ /// For C#: /// "USystem" -> <namespace name="System" /> /// "AS USystem" -> <alias name="S" target="System" kind="namespace" /> /// "AC TSystem.Console" -> <alias name="C" target="System.Console" kind="type" /> /// "AS ESystem alias" -> <alias name="S" qualifier="alias" target="System" kind="type" /> /// "XOldLib" -> <extern alias="OldLib" /> /// "ZOldLib assembly" -> <externinfo name="OldLib" assembly="assembly" /> /// "ESystem alias" -> <namespace qualifier="alias" name="System" /> /// ]]> /// </remarks> public static void ParseCSharpImportString(string import, out string alias, out string externAlias, out string target, out ImportTargetKind kind) { if (import == null) { throw new ArgumentNullException("import"); } if (import.Length == 0) { throw new ArgumentException(import, "import"); } switch (import[0]) { case 'U': // C# using alias = null; externAlias = null; target = import.Substring(1); kind = ImportTargetKind.Namespace; return; case 'E': // C# using // NOTE: Dev12 has related cases "I" and "O" in EMITTER::ComputeDebugNamespace, // but they were probably implementation details that do not affect roslyn. if (!TrySplit(import, 1, ' ', out target, out externAlias)) { throw new ArgumentException(import, "import"); } alias = null; kind = ImportTargetKind.Namespace; return; case 'A': // C# type or namespace alias if (!TrySplit(import, 1, ' ', out alias, out target)) { throw new ArgumentException(import, "import"); } switch (target[0]) { case 'U': kind = ImportTargetKind.Namespace; target = target.Substring(1); externAlias = null; return; case 'T': kind = ImportTargetKind.Type; target = target.Substring(1); externAlias = null; return; case 'E': kind = ImportTargetKind.Namespace; // Never happens for types. if (!TrySplit(target, 1, ' ', out target, out externAlias)) { throw new ArgumentException(import, "import"); } return; default: throw new ArgumentException(import, "import"); } case 'X': // C# extern alias (in file) externAlias = import.Substring(1); alias = null; target = null; kind = ImportTargetKind.Assembly; return; case 'Z': // C# extern alias (module-level) if (!TrySplit(import, 1, ' ', out externAlias, out target)) { throw new ArgumentException(import, "import"); } alias = null; kind = ImportTargetKind.Assembly; return; default: throw new ArgumentException(import, "import"); } }
/// <summary> /// Parse a string representing a VB import statement. /// </summary> /// <exception cref="ArgumentNullException"><paramref name="import"/> is null.</exception> /// <exception cref="ArgumentException">Format of <paramref name="import"/> is not valid.</exception> public static bool TryParseVisualBasicImportString(string import, out string alias, out string target, out ImportTargetKind kind, out ImportScope scope) { alias = null; target = null; kind = default(ImportTargetKind); scope = default(ImportScope); if (import == null) { return false; } // VB current namespace if (import.Length == 0) { alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return true; } int pos = 0; switch (import[pos]) { case '&': // Indicates the presence of embedded PIA types from a given assembly. No longer required (as of Roslyn). case '$': case '#': // From ProcedureContext::LoadImportsAndDefaultNamespaceNormal: // "Module Imports and extension types are no longer needed since we are not doing custom name lookup" alias = null; target = import; kind = ImportTargetKind.Defunct; scope = ImportScope.Unspecified; return true; case '*': // VB default namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.DefaultNamespace; scope = ImportScope.Unspecified; return true; case '@': // VB cases other than default and current namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; if (pos >= import.Length) { return false; } scope = ImportScope.Unspecified; switch (import[pos]) { case 'F': scope = ImportScope.File; pos++; break; case 'P': scope = ImportScope.Project; pos++; break; } if (pos >= import.Length) { return false; } switch (import[pos]) { case 'A': pos++; if (import[pos] != ':') { return false; } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { return false; } kind = ImportTargetKind.NamespaceOrType; return true; case 'X': pos++; if (import[pos] != ':') { return false; } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { return false; } kind = ImportTargetKind.XmlNamespace; return true; case 'T': pos++; if (import[pos] != ':') { return false; } pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Type; return true; case ':': pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Namespace; return true; default: alias = null; target = import.Substring(pos); kind = ImportTargetKind.MethodToken; return true; } default: // VB current namespace alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return true; } }
/// <summary> /// Parse a string representing a C# using (or extern alias) directive. /// </summary> /// <remarks> /// <![CDATA[ /// For C#: /// "USystem" -> <namespace name="System" /> /// "AS USystem" -> <alias name="S" target="System" kind="namespace" /> /// "AC TSystem.Console" -> <alias name="C" target="System.Console" kind="type" /> /// "AS ESystem alias" -> <alias name="S" qualifier="alias" target="System" kind="type" /> /// "XOldLib" -> <extern alias="OldLib" /> /// "ZOldLib assembly" -> <externinfo name="OldLib" assembly="assembly" /> /// "ESystem alias" -> <namespace qualifier="alias" name="System" /> /// "TSystem.Math" -> <type name="System.Math" /> /// ]]> /// </remarks> public static bool TryParseCSharpImportString(string import, out string alias, out string externAlias, out string target, out ImportTargetKind kind) { alias = null; externAlias = null; target = null; kind = default(ImportTargetKind); if (string.IsNullOrEmpty(import)) { return false; } switch (import[0]) { case 'U': // C# (namespace) using alias = null; externAlias = null; target = import.Substring(1); kind = ImportTargetKind.Namespace; return true; case 'E': // C# (namespace) using // NOTE: Dev12 has related cases "I" and "O" in EMITTER::ComputeDebugNamespace, // but they were probably implementation details that do not affect Roslyn. if (!TrySplit(import, 1, ' ', out target, out externAlias)) { return false; } alias = null; kind = ImportTargetKind.Namespace; return true; case 'T': // C# (type) using alias = null; externAlias = null; target = import.Substring(1); kind = ImportTargetKind.Type; return true; case 'A': // C# type or namespace alias if (!TrySplit(import, 1, ' ', out alias, out target)) { return false; } switch (target[0]) { case 'U': kind = ImportTargetKind.Namespace; target = target.Substring(1); externAlias = null; return true; case 'T': kind = ImportTargetKind.Type; target = target.Substring(1); externAlias = null; return true; case 'E': kind = ImportTargetKind.Namespace; // Never happens for types. if (!TrySplit(target, 1, ' ', out target, out externAlias)) { return false; } return true; default: return false; } case 'X': // C# extern alias (in file) externAlias = null; alias = import.Substring(1); // For consistency with the portable format, store it in alias, rather than externAlias. target = null; kind = ImportTargetKind.Assembly; return true; case 'Z': // C# extern alias (module-level) // For consistency with the portable format, store it in alias, rather than externAlias. if (!TrySplit(import, 1, ' ', out alias, out target)) { return false; } externAlias = null; kind = ImportTargetKind.Assembly; return true; default: return false; } }
public ImportTarget(ImportTargetKind kind) { this.kind = kind; }
/// <summary> /// Parse a string representing a VB import statement. /// </summary> /// <exception cref="ArgumentNullException"><paramref name="import"/> is null.</exception> /// <exception cref="ArgumentException">Format of <paramref name="import"/> is not valid.</exception> public static bool TryParseVisualBasicImportString(string import, out string alias, out string target, out ImportTargetKind kind, out ImportScope scope) { alias = null; target = null; kind = default(ImportTargetKind); scope = default(ImportScope); if (import == null) { return(false); } // VB current namespace if (import.Length == 0) { alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return(true); } int pos = 0; switch (import[pos]) { case '&': // Indicates the presence of embedded PIA types from a given assembly. No longer required (as of Roslyn). case '$': case '#': // From ProcedureContext::LoadImportsAndDefaultNamespaceNormal: // "Module Imports and extension types are no longer needed since we are not doing custom name lookup" alias = null; target = import; kind = ImportTargetKind.Defunct; scope = ImportScope.Unspecified; return(true); case '*': // VB default namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.DefaultNamespace; scope = ImportScope.Unspecified; return(true); case '@': // VB cases other than default and current namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; if (pos >= import.Length) { return(false); } scope = ImportScope.Unspecified; switch (import[pos]) { case 'F': scope = ImportScope.File; pos++; break; case 'P': scope = ImportScope.Project; pos++; break; } if (pos >= import.Length) { return(false); } switch (import[pos]) { case 'A': pos++; if (import[pos] != ':') { return(false); } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { return(false); } kind = ImportTargetKind.NamespaceOrType; return(true); case 'X': pos++; if (import[pos] != ':') { return(false); } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { return(false); } kind = ImportTargetKind.XmlNamespace; return(true); case 'T': pos++; if (import[pos] != ':') { return(false); } pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Type; return(true); case ':': pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Namespace; return(true); default: alias = null; target = import.Substring(pos); kind = ImportTargetKind.MethodToken; return(true); } default: // VB current namespace alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return(true); } }
/// <summary> /// Parse a string representing a C# using (or extern alias) directive. /// </summary> /// <remarks> /// <![CDATA[ /// For C#: /// "USystem" -> <namespace name="System" /> /// "AS USystem" -> <alias name="S" target="System" kind="namespace" /> /// "AC TSystem.Console" -> <alias name="C" target="System.Console" kind="type" /> /// "AS ESystem alias" -> <alias name="S" qualifier="alias" target="System" kind="type" /> /// "XOldLib" -> <extern alias="OldLib" /> /// "ZOldLib assembly" -> <externinfo name="OldLib" assembly="assembly" /> /// "ESystem alias" -> <namespace qualifier="alias" name="System" /> /// "TSystem.Math" -> <type name="System.Math" /> /// ]]> /// </remarks> public static bool TryParseCSharpImportString(string import, out string alias, out string externAlias, out string target, out ImportTargetKind kind) { alias = null; externAlias = null; target = null; kind = default(ImportTargetKind); if (string.IsNullOrEmpty(import)) { return(false); } switch (import[0]) { case 'U': // C# (namespace) using alias = null; externAlias = null; target = import.Substring(1); kind = ImportTargetKind.Namespace; return(true); case 'E': // C# (namespace) using // NOTE: Dev12 has related cases "I" and "O" in EMITTER::ComputeDebugNamespace, // but they were probably implementation details that do not affect roslyn. if (!TrySplit(import, 1, ' ', out target, out externAlias)) { return(false); } alias = null; kind = ImportTargetKind.Namespace; return(true); case 'T': // C# (type) using alias = null; externAlias = null; target = import.Substring(1); kind = ImportTargetKind.Type; return(true); case 'A': // C# type or namespace alias if (!TrySplit(import, 1, ' ', out alias, out target)) { return(false); } switch (target[0]) { case 'U': kind = ImportTargetKind.Namespace; target = target.Substring(1); externAlias = null; return(true); case 'T': kind = ImportTargetKind.Type; target = target.Substring(1); externAlias = null; return(true); case 'E': kind = ImportTargetKind.Namespace; // Never happens for types. if (!TrySplit(target, 1, ' ', out target, out externAlias)) { return(false); } return(true); default: return(false); } case 'X': // C# extern alias (in file) externAlias = null; alias = import.Substring(1); // For consistency with the portable format, store it in alias, rather than externAlias. target = null; kind = ImportTargetKind.Assembly; return(true); case 'Z': // C# extern alias (module-level) // For consistency with the portable format, store it in alias, rather than externAlias. if (!TrySplit(import, 1, ' ', out alias, out target)) { return(false); } externAlias = null; kind = ImportTargetKind.Assembly; return(true); default: return(false); } }
private static void ReadVisualBasicImportsDebugInfo( ISymUnmanagedReader reader, int methodToken, int methodVersion, out ImmutableArray <ImmutableArray <ImportRecord> > importRecordGroups, out string defaultNamespaceName) { importRecordGroups = ImmutableArray <ImmutableArray <ImportRecord> > .Empty; var importStrings = CustomDebugInfoReader.GetVisualBasicImportStrings( methodToken, KeyValuePair.Create(reader, methodVersion), (token, arg) => GetImportStrings(arg.Key, token, arg.Value)); if (importStrings.IsDefault) { defaultNamespaceName = ""; return; } defaultNamespaceName = null; var projectLevelImportRecords = ArrayBuilder <ImportRecord> .GetInstance(); var fileLevelImportRecords = ArrayBuilder <ImportRecord> .GetInstance(); foreach (string importString in importStrings) { Debug.Assert(importString != null); if (importString.Length > 0 && importString[0] == '*') { string alias = null; string target = null; ImportTargetKind kind = 0; VBImportScopeKind scope = 0; if (!CustomDebugInfoReader.TryParseVisualBasicImportString(importString, out alias, out target, out kind, out scope)) { Debug.WriteLine($"Unable to parse import string '{importString}'"); continue; } else if (kind == ImportTargetKind.Defunct) { continue; } Debug.Assert(alias == null); // The default namespace is never aliased. Debug.Assert(target != null); Debug.Assert(kind == ImportTargetKind.DefaultNamespace); // We only expect to see one of these, but it looks like ProcedureContext::LoadImportsAndDefaultNamespaceNormal // implicitly uses the last one if there are multiple. Debug.Assert(defaultNamespaceName == null); defaultNamespaceName = target; } else { ImportRecord importRecord; VBImportScopeKind scope = 0; if (TryCreateImportRecordFromVisualBasicImportString(importString, out importRecord, out scope)) { if (scope == VBImportScopeKind.Project) { projectLevelImportRecords.Add(importRecord); } else { Debug.Assert(scope == VBImportScopeKind.File || scope == VBImportScopeKind.Unspecified); fileLevelImportRecords.Add(importRecord); } } else { Debug.WriteLine($"Failed to parse import string {importString}"); } } } importRecordGroups = ImmutableArray.Create( fileLevelImportRecords.ToImmutableAndFree(), projectLevelImportRecords.ToImmutableAndFree()); defaultNamespaceName = defaultNamespaceName ?? ""; }
/// <summary> /// Parse a string representing a VB import statement. /// </summary> /// <exception cref="ArgumentNullException"><paramref name="import"/> is null.</exception> /// <exception cref="ArgumentException">Format of <paramref name="import"/> is not valid.</exception> public static void ParseVisualBasicImportString(string import, out string alias, out string target, out ImportTargetKind kind, out ImportScope scope) { if (import == null) { throw new ArgumentNullException("import"); } if (import.Length == 0) // VB current namespace { alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return; } int pos = 0; switch (import[pos]) { case '*': // VB default namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.DefaultNamespace; scope = ImportScope.Unspecified; return; case '@': // VB cases other than default and current namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; if (pos >= import.Length) { throw new ArgumentException(import, "import"); } scope = ImportScope.Unspecified; switch (import[pos]) { case 'F': scope = ImportScope.File; pos++; break; case 'P': scope = ImportScope.Project; pos++; break; } if (pos >= import.Length) { throw new ArgumentException(import, "import"); } switch (import[pos]) { case 'A': pos++; if (import[pos] != ':') { throw new ArgumentException(import, "import"); } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { throw new ArgumentException(import, "import"); } kind = ImportTargetKind.NamespaceOrType; return; case 'X': pos++; if (import[pos] != ':') { throw new ArgumentException(import, "import"); } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { throw new ArgumentException(import, "import"); } kind = ImportTargetKind.XmlNamespace; return; case 'T': pos++; if (import[pos] != ':') { throw new ArgumentException(import, "import"); } pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Type; return; case ':': pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Namespace; return; default: alias = null; target = import.Substring(pos); kind = ImportTargetKind.MethodToken; return; } default: // VB current namespace alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return; } }
/// <summary> /// Parse a string representing a C# using (or extern alias) directive. /// </summary> /// <remarks> /// <![CDATA[ /// For C#: /// "USystem" -> <namespace name="System" /> /// "AS USystem" -> <alias name="S" target="System" kind="namespace" /> /// "AC TSystem.Console" -> <alias name="C" target="System.Console" kind="type" /> /// "AS ESystem alias" -> <alias name="S" qualifier="alias" target="System" kind="type" /> /// "XOldLib" -> <extern alias="OldLib" /> /// "ZOldLib assembly" -> <externinfo name="OldLib" assembly="assembly" /> /// "ESystem alias" -> <namespace qualifier="alias" name="System" /> /// ]]> /// </remarks> public static void ParseCSharpImportString(string import, out string alias, out string externAlias, out string target, out ImportTargetKind kind) { if (import == null) { throw new ArgumentNullException("import"); } if (import.Length == 0) { throw new ArgumentException(import, "import"); } switch (import[0]) { case 'U': // C# using alias = null; externAlias = null; target = import.Substring(1); kind = ImportTargetKind.Namespace; return; case 'E': // C# using // NOTE: Dev12 has related cases "I" and "O" in EMITTER::ComputeDebugNamespace, // but they were probably implementation details that do not affect roslyn. if (!TrySplit(import, 1, ' ', out target, out externAlias)) { throw new ArgumentException(import, "import"); } alias = null; kind = ImportTargetKind.Namespace; return; case 'A': // C# type or namespace alias if (!TrySplit(import, 1, ' ', out alias, out target)) { throw new ArgumentException(import, "import"); } switch (target[0]) { case 'U': kind = ImportTargetKind.Namespace; target = target.Substring(1); externAlias = null; return; case 'T': kind = ImportTargetKind.Type; target = target.Substring(1); externAlias = null; return; case 'E': kind = ImportTargetKind.Namespace; // Never happens for types. if (!TrySplit(target, 1, ' ', out target, out externAlias)) { throw new ArgumentException(import, "import"); } return; default: throw new ArgumentException(import, "import"); } case 'X': // C# extern alias (in file) externAlias = import.Substring(1); alias = null; target = null; kind = ImportTargetKind.Assembly; return; case 'Z': // C# extern alias (module-level) if (!TrySplit(import, 1, ' ', out externAlias, out target)) { throw new ArgumentException(import, "import"); } alias = null; kind = ImportTargetKind.Assembly; return; default: throw new ArgumentException(import, "import"); } }
public ImportTarget(ImportTargetKind kind) { this.kind = kind; }
/// <summary> /// Parse a string representing a VB import statement. /// </summary> /// <exception cref="ArgumentNullException"><paramref name="import"/> is null.</exception> /// <exception cref="ArgumentException">Format of <paramref name="import"/> is not valid.</exception> public static bool TryParseVisualBasicImportString(string import, out string alias, out string target, out ImportTargetKind kind, out ImportScope scope) { alias = null; target = null; kind = default(ImportTargetKind); scope = default(ImportScope); if (import == null) { return false; } if (import.Length == 0) // VB current namespace { alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return true; } // TODO (acasey): looks like we missed some cases (e.g. '$', '#', '&') // See ProcedureContext::LoadImportsAndDefaultNamespaceNormal. int pos = 0; switch (import[pos]) { case '*': // VB default namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.DefaultNamespace; scope = ImportScope.Unspecified; return true; case '@': // VB cases other than default and current namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; if (pos >= import.Length) { return false; } scope = ImportScope.Unspecified; switch (import[pos]) { case 'F': scope = ImportScope.File; pos++; break; case 'P': scope = ImportScope.Project; pos++; break; } if (pos >= import.Length) { return false; } switch (import[pos]) { case 'A': pos++; if (import[pos] != ':') { return false; } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { return false; } kind = ImportTargetKind.NamespaceOrType; return true; case 'X': pos++; if (import[pos] != ':') { return false; } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { return false; } kind = ImportTargetKind.XmlNamespace; return true; case 'T': pos++; if (import[pos] != ':') { return false; } pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Type; return true; case ':': pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Namespace; return true; default: alias = null; target = import.Substring(pos); kind = ImportTargetKind.MethodToken; return true; } default: // VB current namespace alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return true; } }
/// <summary> /// Parse a string representing a VB import statement. /// </summary> /// <exception cref="ArgumentNullException"><paramref name="import"/> is null.</exception> /// <exception cref="ArgumentException">Format of <paramref name="import"/> is not valid.</exception> public static bool TryParseVisualBasicImportString(string import, out string alias, out string target, out ImportTargetKind kind, out ImportScope scope) { alias = null; target = null; kind = default(ImportTargetKind); scope = default(ImportScope); if (import == null) { return(false); } if (import.Length == 0) // VB current namespace { alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return(true); } // TODO (acasey): looks like we missed some cases (e.g. '$', '#', '&') // See ProcedureContext::LoadImportsAndDefaultNamespaceNormal. int pos = 0; switch (import[pos]) { case '*': // VB default namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.DefaultNamespace; scope = ImportScope.Unspecified; return(true); case '@': // VB cases other than default and current namespace // see PEBuilder.cpp in vb\language\CodeGen pos++; if (pos >= import.Length) { return(false); } scope = ImportScope.Unspecified; switch (import[pos]) { case 'F': scope = ImportScope.File; pos++; break; case 'P': scope = ImportScope.Project; pos++; break; } if (pos >= import.Length) { return(false); } switch (import[pos]) { case 'A': pos++; if (import[pos] != ':') { return(false); } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { return(false); } kind = ImportTargetKind.NamespaceOrType; return(true); case 'X': pos++; if (import[pos] != ':') { return(false); } pos++; if (!TrySplit(import, pos, '=', out alias, out target)) { return(false); } kind = ImportTargetKind.XmlNamespace; return(true); case 'T': pos++; if (import[pos] != ':') { return(false); } pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Type; return(true); case ':': pos++; alias = null; target = import.Substring(pos); kind = ImportTargetKind.Namespace; return(true); default: alias = null; target = import.Substring(pos); kind = ImportTargetKind.MethodToken; return(true); } default: // VB current namespace alias = null; target = import; kind = ImportTargetKind.CurrentNamespace; scope = ImportScope.Unspecified; return(true); } }