/// <summary> /// Finds all of the matches for this type /// </summary> /// <returns>All of the type definitions that match this type use</returns> public override IEnumerable <ITypeDefinition> FindMatches() { // if this is a built-in type, then just return that otherwise, go hunting for matching // types if (BuiltInTypeFactory.IsBuiltIn(this)) { yield return(BuiltInTypeFactory.GetBuiltIn(this)); } else if (null != Prefix) { var matches = from prefixMatch in Prefix.FindMatches() from match in prefixMatch.GetChildScopesWithId <ITypeDefinition>(this.Name) select match; foreach (var match in matches) { yield return(match); } } else { // First, just call AbstractUse.FindMatches() this will search everything in // ParentScope.GetParentScopesAndSelf<TypeDefinition>() for a matching type and // return it foreach (var match in base.FindMatches()) { yield return(match); } } }
/// <summary> /// Finds all of the matches for this type /// </summary> /// <returns>All of the type definitions that match this type use</returns> public override IEnumerable <TypeDefinition> ResolveType() { if (ParentStatement == null) { throw new InvalidOperationException("ParentStatement is null"); } // if this is a built-in type, then just return that // otherwise, go hunting for matching types if (BuiltInTypeFactory.IsBuiltIn(this)) { return(Enumerable.Repeat(BuiltInTypeFactory.GetBuiltIn(this), 1)); } //If there's a prefix, resolve that and search under results if (Prefix != null) { return(Prefix.FindMatches().SelectMany(ns => ns.GetNamedChildren <TypeDefinition>(this.Name))); } //If there's a calling expression, match and search under results var callingScopes = GetCallingScope(); if (callingScopes != null) { IEnumerable <TypeDefinition> matches = Enumerable.Empty <TypeDefinition>(); foreach (var scope in callingScopes) { var localMatches = scope.GetNamedChildren <TypeDefinition>(this.Name).ToList(); var callingType = scope as TypeDefinition; if (!localMatches.Any() && callingType != null) { //also search under the base types of the calling scope matches = matches.Concat(callingType.SearchParentTypes <TypeDefinition>(this.Name, e => true)); } else { matches = matches.Concat(localMatches); } } return(matches); } //handle C# var keyword if (Name == "var" && ProgrammingLanguage == Language.CSharp) { var varDecl = ParentExpression as VariableDeclaration; if (varDecl != null) { if (varDecl.Initializer != null) { return(varDecl.Initializer.ResolveType()); } if (varDecl.Range != null) { //TODO: update to determine type of items within the collection and return that return(varDecl.Range.ResolveType()); } return(Enumerable.Empty <TypeDefinition>()); } } //search enclosing scopes and base types foreach (var scope in ParentStatement.GetAncestors <NamedScope>()) { var matches = scope.GetNamedChildren <TypeDefinition>(this).Where(SignatureMatches).ToList(); if (matches.Any()) { return(matches); } var typeDef = scope as TypeDefinition; if (typeDef != null) { var baseTypeMatches = typeDef.SearchParentTypes <TypeDefinition>(this.Name, SignatureMatches).ToList(); if (baseTypeMatches.Any()) { return(baseTypeMatches); } } } //search if there is an alias for this name foreach (var alias in GetAliases()) { if (alias.AliasName == this.Name) { var targetName = alias.Target as NameUse; if (targetName == null) { //Target is not a NameUse, probably an Expression targetName = alias.Target.GetDescendantsAndSelf <NameUse>().LastOrDefault(); } if (targetName != null) { return(targetName.FindMatches().OfType <TypeDefinition>()); } } } //we didn't find it locally, search under imported namespaces return(from import in GetImports() from match in import.ImportedNamespace.GetDescendantsAndSelf <NameUse>().Last().FindMatches().OfType <NamedScope>() from child in match.GetNamedChildren <TypeDefinition>(this.Name) select child); }