/// <summary> /// Find named scopes that match this named scope use. /// </summary> /// <returns>An enumerable of named scopes with the same name as this use</returns> public override IEnumerable <INamedScope> FindMatches() { if (ChildScopeUse != null) { var globalScope = ParentScope.GetParentScopesAndSelf <INamespaceDefinition>().Where(p => p.IsGlobal).FirstOrDefault(); if (null == globalScope) { throw new ScopeDetachedException(this.ParentScope); } INamedScopeUse current = ChildScopeUse; IEnumerable <INamedScope> matches = null; while (current != null) { if (matches == null) { matches = globalScope.GetChildScopesWithId <INamedScope>(current.Name); } else { matches = GetChildScopesWithName(matches, current.Name); } current = current.ChildScopeUse; } return(matches == null ? Enumerable.Empty <INamedScope>() : matches); } else { return(base.FindMatches()); } }
/// <summary> /// Selects the most likely unresolved path to this element. Currently, it always selects /// the first element. Calling this sets <see cref="UnresolvedParentScopeInUse"/>. /// </summary> /// <returns><see cref="UnresolvedParentScopeInUse"/> unless there are no /// <see cref="ParentScopeCandidates"/>. Then it returns null</returns> public INamedScopeUse SelectUnresolvedScope() { if (ParentScopeCandidates.Any()) { UnresolvedParentScopeInUse = ParentScopeCandidates.First(); return(UnresolvedParentScopeInUse); } return(null); }
public static bool NamedScopeUsesAreEqual(INamedScopeUse a, INamedScopeUse b) { if (a == b) { return(true); } return(a.Name == b.Name && LocationsAreEqual(a.Location, b.Location) && a.ProgrammingLanguage == b.ProgrammingLanguage && NamedScopeUsesAreEqual(a.ChildScopeUse, b.ChildScopeUse)); }
public static void VerifyPrefixValues(IEnumerable <string> expected, INamedScopeUse use) { var prefix = use; Collection <string> prefixes = new Collection <string>(); do { prefixes.Add(prefix.Name); prefix = prefix.ChildScopeUse; } while(prefix != null); CollectionAssert.AreEqual(expected as IEnumerable, prefixes as IEnumerable); }
/// <summary> /// Constructs the full name for this named scope use by combining this scope with all of /// its <see cref="ChildScopeUse">children</see> /// </summary> /// <returns>The full name</returns> public string GetFullName() { StringBuilder sb = new StringBuilder(); INamedScopeUse current = this; while (current != null) { sb.Append(current.Name); current = current.ChildScopeUse; if (null != current) { sb.Append('.'); } } return(sb.ToString()); }
/// <summary> /// Finds all of the matching type definitions for all of the variable declarations that /// match this variable use /// </summary> /// <returns>An enumerable of matching type definitions</returns> public IEnumerable <ITypeDefinition> FindMatchingTypes() { IEnumerable <ITypeDefinition> typeDefinitions; if (this.Name == "this" || (this.Name == "base" && this.ProgrammingLanguage == Language.CSharp)) { typeDefinitions = TypeDefinition.GetTypeForKeyword(this); } else { var matchingVariables = FindMatches(); if (matchingVariables.Any()) { typeDefinitions = from declaration in matchingVariables where declaration.VariableType != null from definition in declaration.VariableType.FindMatches() select definition; } else { var tempTypeUse = new TypeUse() { Name = this.Name, ParentScope = this.ParentScope, ProgrammingLanguage = this.ProgrammingLanguage, }; if (CallingObject != null && CallingObject is IVariableUse) { var caller = CallingObject as IVariableUse; Stack <INamedScopeUse> callerStack = new Stack <INamedScopeUse>(); while (caller != null) { var scopeUse = new NamedScopeUse() { Name = caller.Name, ProgrammingLanguage = this.ProgrammingLanguage, }; callerStack.Push(scopeUse); caller = caller.CallingObject as IVariableUse; } INamedScopeUse prefix = null, last = null; foreach (var current in callerStack) { if (null == prefix) { prefix = current; last = prefix; } else { last.ChildScopeUse = current; last = current; } } prefix.ParentScope = this.ParentScope; tempTypeUse.Prefix = prefix; } tempTypeUse.AddAliases(this.Aliases); typeDefinitions = tempTypeUse.FindMatchingTypes(); } } return(typeDefinitions); }