public NamedScope Merge(NamedScope otherNamedScope) { if (null == otherNamedScope) { throw new ArgumentNullException("otherNamedScope"); } return(Merge <NamedScope>(this, otherNamedScope)); }
/// <summary> /// Copy constructor /// </summary> /// <param name="otherScope">The scope to copy from</param> public NamedScope(NamedScope otherScope) : base(otherScope) { Accessibility = otherScope.Accessibility; Name = otherScope.Name; ParentScopeCandidates = new Collection<NamedScopeUse>(); foreach(var candidate in otherScope.ParentScopeCandidates) { ParentScopeCandidates.Add(candidate); } UnresolvedParentScopeInUse = otherScope.UnresolvedParentScopeInUse; }
/// <summary> /// Merges this namespace definition with <paramref name="otherScope"/>. This happens when <c>otherScope.CanBeMergedInto(this)</c> evaluates to true. /// </summary> /// <param name="otherScope">the scope to merge with</param> /// <returns>a new namespace definition from this and otherScope, or null if they couldn't be merged.</returns> public override NamedScope Merge(NamedScope otherScope) { NamespaceDefinition mergedScope = null; if(otherScope != null) { if(otherScope.CanBeMergedInto(this)) { mergedScope = new NamespaceDefinition(this); mergedScope.AddFrom(otherScope); } } return mergedScope; }
/// <summary> /// Copy constructor /// </summary> /// <param name="otherScope">The scope to copy from</param> public NamedScope(NamedScope otherScope) : base(otherScope) { Accessibility = otherScope.Accessibility; Name = otherScope.Name; ParentScopeCandidates = new Collection <INamedScopeUse>(); foreach (var candidate in otherScope.ParentScopeCandidates) { ParentScopeCandidates.Add(candidate); } UnresolvedParentScopeInUse = otherScope.UnresolvedParentScopeInUse; }
/// <summary> /// Creates a <see cref="NamedScope"/> object from this use (along with all of its /// descendants based on <see cref="ChildScopeUse"/>). /// </summary> /// <returns>A new named scope based on this use</returns> public virtual INamedScope CreateScope() { INamedScope scope = new NamedScope() { Name = this.Name, ProgrammingLanguage = this.ProgrammingLanguage, }; scope.AddSourceLocation(this.Location); if (null != this.ChildScopeUse) { scope.AddChildScope(ChildScopeUse.CreateScope()); } return(scope); }
/// <summary> /// Removes <paramref name="namedChild"/> from the name cache. /// If <paramref name="namedChild"/>is null, then nothing happens. /// </summary> /// <param name="namedChild">The named child to remove</param> private void RemoveNamedChild(NamedScope namedChild) { if (null == namedChild) { return; } List <NamedScope> cacheForName; if (_nameCache.TryGetValue(namedChild.Name, out cacheForName)) { cacheForName.Remove(namedChild); if (cacheForName.Count == 0) { _nameCache.Remove(namedChild.Name); } } }
/// <summary> /// Returns an enumerable of possible NamedScopes that this prefix might be referring to. /// </summary> /// <param name="root">The root NamedScope from which to begin searching for matches.</param> public IEnumerable<NamedScope> FindMatches(NamedScope root) { var prefixes = Names.ToList(); var prefixMap = new Dictionary<NameUse, List<NamedScope>>(); for(int i = 0; i < prefixes.Count; i++) { if(0 == i) { prefixMap[prefixes[i]] = (from child in root.ChildStatements.OfType<NamedScope>() where child.Name == prefixes[i].Name select child).ToList(); } else { prefixMap[prefixes[i]] = (from candidate in prefixMap[prefixes[i - 1]] from child in candidate.ChildStatements.OfType<NamedScope>() where child.Name == prefixes[i].Name select child).ToList(); } } return prefixMap[prefixes[prefixes.Count - 1]]; }
/// <summary> /// Adds <paramref name="namedChild"/> to the name cache. /// If <paramref name="namedChild"/> is null, then nothing happens. /// </summary> /// <param name="namedChild">The named child to add</param> private void AddNamedChild(NamedScope namedChild) { if (null == namedChild) { return; } List <NamedScope> cacheForName; if (_nameCache.TryGetValue(namedChild.Name, out cacheForName)) { cacheForName.Add(namedChild); } else { _nameCache[namedChild.Name] = new List <NamedScope>() { namedChild }; } }
/// <summary> /// Merges two NamedVariableScopes together. It works like this: <list type="bullet"> /// <item><description>If this is the same type or more specific than /// <paramref name="otherScope"/>, then create a new merged NamedScope from /// <paramref name="otherScope"/>and this.</description></item> <item><description>If /// <paramref name="otherScope"/>is more specific than this, call /// <c>otherScope.Merge</c></description></item> </list> /// </summary> /// <param name="otherScope">The scope to merge with</param> /// <returns>The new merged scope; null if they couldn't be merged</returns> public virtual INamedScope Merge(INamedScope otherScope) { INamedScope mergedScope = null; if (otherScope != null) { if (otherScope.CanBeMergedInto(this)) { // this and other scope can be merged normally either they are the same type or // this is a subclass of NamedScope and otherScope is a NamedScope mergedScope = new NamedScope(this); mergedScope.AddFrom(otherScope); } else if (this.CanBeMergedInto(otherScope) && !otherScope.CanBeMergedInto(this)) { // this is a NamedScope and otherScope is a subclass useful information (type, // method, or namespace data) are in otherScope mergedScope = otherScope.Merge(this); } } return(mergedScope); }
protected void MapPrefix(NamedScope tail) { var data = Enumerable.Zip(Prefix.Names.Reverse(), tail.GetAncestorsAndSelf <NamedScope>(), (name, scope) => { return(new { IsValid = (name.Name == scope.Name), Location = name.Location, Scope = scope, }); }); foreach (var d in data) { if (d.IsValid) { d.Scope.AddLocation(d.Location); } else { throw new SrcMLException("not a valid scope for this prefix"); } } PrefixIsResolved = true; }
/// <summary> /// Returns an enumerable of possible NamedScopes that this prefix might be referring to. /// </summary> /// <param name="root">The root NamedScope from which to begin searching for matches.</param> public IEnumerable <NamedScope> FindMatches(NamedScope root) { var prefixes = Names.ToList(); var prefixMap = new Dictionary <NameUse, List <NamedScope> >(); for (int i = 0; i < prefixes.Count; i++) { if (0 == i) { prefixMap[prefixes[i]] = (from child in root.ChildStatements.OfType <NamedScope>() where child.Name == prefixes[i].Name select child).ToList(); } else { prefixMap[prefixes[i]] = (from candidate in prefixMap[prefixes[i - 1]] from child in candidate.ChildStatements.OfType <NamedScope>() where child.Name == prefixes[i].Name select child).ToList(); } } return(prefixMap[prefixes[prefixes.Count - 1]]); }
/// <summary> /// Casts <paramref name="otherScope"/> to a <see cref="NamespaceDefinition"/> and calls <see cref="CanBeMergedInto(NamespaceDefinition)"/> /// </summary> /// <param name="otherScope">The scope to test</param> /// <returns>true if <see cref="CanBeMergedInto(NamespaceDefinition)"/> evaluates to true.</returns> public override bool CanBeMergedInto(NamedScope otherScope) { return this.CanBeMergedInto(otherScope as NamespaceDefinition); }
/// <summary> /// Sets up unresolved links between this and <paramref name="childScope"/> if needed. /// </summary> /// <param name="childScope">The child scope to add</param> protected void AddNamedChildScope(NamedScope childScope) { var scopeToAdd = childScope; if(childScope.UnresolvedParentScopeInUse == null && childScope.ParentScopeCandidates.Any()) { var selectedScope = childScope.SelectUnresolvedScope(); scopeToAdd = selectedScope.CreateScope(); Scope latest = scopeToAdd, current; do { current = latest; latest = current.ChildScopes.FirstOrDefault(); } while(latest != null); current.AddChildScope(childScope); } base.AddChildScope(scopeToAdd); }
/// <summary> /// Merges two NamedVariableScopes together. It works like this: /// <list type="bullet"> /// <item><description>If this is the same type or more specific than <paramref name="otherScope"/>, then create a new merged NamedScope /// from <paramref name="otherScope"/> and this.</description></item> /// <item><description>If <paramref name="otherScope"/> is more specific than this, call <c>otherScope.Merge</c></description></item> /// </list> /// </summary> /// <param name="otherScope">The scope to merge with</param> /// <returns>The new merged scope; null if they couldn't be merged</returns> public virtual NamedScope Merge(NamedScope otherScope) { NamedScope mergedScope = null; if(otherScope != null) { if(otherScope.CanBeMergedInto(this)) { // this and other scope can be merged normally // either they are the same type or // this is a subclass of NamedScope and otherScope is a NamedScope mergedScope = new NamedScope(this); mergedScope.AddFrom(otherScope); } else if(this.CanBeMergedInto(otherScope) && !otherScope.CanBeMergedInto(this)) { // this is a NamedScope and otherScope is a subclass // useful information (type, method, or namespace data) are in otherScope mergedScope = otherScope.Merge(this); } } return mergedScope; }
/// <summary> /// Two NamedScope objects can be merged if they share the same name. /// </summary> /// <param name="otherScope">The scope to test</param> /// <returns>true if the two objects have the same <see cref="Name"/>. False, /// otherwise.</returns> public virtual bool CanBeMergedInto(NamedScope otherScope) { return(null != otherScope && this.Name == otherScope.Name); }
/// <summary> /// Two NamedScope objects can be merged if they share the same name. /// </summary> /// <param name="otherScope">The scope to test</param> /// <returns>true if the two objects have the same <see cref="Name"/>. False, otherwise.</returns> public virtual bool CanBeMergedInto(NamedScope otherScope) { return (null != otherScope && this.Name == otherScope.Name); }
/// <summary> /// Merges this method definition with <paramref name="otherScope"/>. This happens when <c>otherScope.CanBeMergedInto(this)</c> evaluates to true. /// </summary> /// <param name="otherScope">the scope to merge with</param> /// <returns>a new method definition from this and otherScope, or null if they couldn't be merged.</returns> public override NamedScope Merge(NamedScope otherScope) { MethodDefinition mergedScope = null; if(otherScope != null) { if(otherScope.CanBeMergedInto(this)) { mergedScope = new MethodDefinition(this); mergedScope.AddFrom(otherScope); if(mergedScope.Accessibility == AccessModifier.None) { mergedScope.Accessibility = otherScope.Accessibility; } } } return mergedScope; }
/// <summary> /// Casts /// <paramref name="otherScope"/>to a <see cref="TypeDefinition"/> and calls /// <see cref="CanBeMergedInto(TypeDefinition)"/> /// </summary> /// <param name="otherScope">The scope to test</param> /// <returns>true if <see cref="CanBeMergedInto(TypeDefinition)"/> evaluates to /// true.</returns> public override bool CanBeMergedInto(NamedScope otherScope) { return(this.CanBeMergedInto(otherScope as TypeDefinition)); }