示例#1
0
        public void TestLocationInMethodDefinition_Cpp()
        {
            ////Foo.h
            //class Foo {
            //public:
            //    int bar(int);
            //}
            var         hXml        = @"<class pos:line=""1"" pos:column=""1"">class <name pos:line=""1"" pos:column=""7"">Foo</name> <block pos:line=""1"" pos:column=""11"">{<private type=""default"" pos:line=""1"" pos:column=""12"">
</private><public pos:line=""2"" pos:column=""1"">public:
    <function_decl><type><name pos:line=""3"" pos:column=""5"">int</name></type> <name pos:line=""3"" pos:column=""9"">bar</name><parameter_list pos:line=""3"" pos:column=""12"">(<param><decl><type><name pos:line=""3"" pos:column=""13"">int</name></type></decl></param>)</parameter_list>;</function_decl>
</public>}</block><decl/></class>";
            var         hUnit       = fileSetup[Language.CPlusPlus].GetFileUnitForXmlSnippet(hXml, "Foo.h");
            INamedScope globalScope = parser[Language.CPlusPlus].ParseFileUnit(hUnit);
            ////Foo.cpp
            //#include "Foo.h"
            //int Foo::bar(int baz) {
            //    return baz + 1;
            //}
            var cppXml  = @"<cpp:include pos:line=""1"" pos:column=""1"">#<cpp:directive pos:line=""1"" pos:column=""2"">include</cpp:directive> <cpp:file><lit:literal type=""string"" pos:line=""1"" pos:column=""10"">""Foo.h""</lit:literal></cpp:file></cpp:include>
<function><type><name pos:line=""2"" pos:column=""1"">int</name></type> <name><name pos:line=""2"" pos:column=""5"">Foo</name><op:operator pos:line=""2"" pos:column=""8"">::</op:operator><name pos:line=""2"" pos:column=""10"">bar</name></name><parameter_list pos:line=""2"" pos:column=""13"">(<param><decl><type><name pos:line=""2"" pos:column=""14"">int</name></type> <name pos:line=""2"" pos:column=""18"">baz</name></decl></param>)</parameter_list> <block pos:line=""2"" pos:column=""23"">{
    <return pos:line=""3"" pos:column=""5"">return <expr><name pos:line=""3"" pos:column=""12"">baz</name> <op:operator pos:line=""3"" pos:column=""16"">+</op:operator> <lit:literal type=""number"" pos:line=""3"" pos:column=""18"">1</lit:literal></expr>;</return>
}</block></function>";
            var cppUnit = fileSetup[Language.CPlusPlus].GetFileUnitForXmlSnippet(cppXml, "Foo.cpp");

            globalScope = globalScope.Merge(parser[Language.CPlusPlus].ParseFileUnit(cppUnit)) as INamedScope;

            var bar = globalScope.ChildScopes.First().ChildScopes.OfType <IMethodDefinition>().First();

            Assert.AreEqual("bar", bar.Name);
            Assert.AreEqual(bar, globalScope.GetScopeForLocation(new SourceLocation("Foo.cpp", 3, 2)));
        }
示例#2
0
 /// <summary>
 /// Checks to see if this is an alias for
 /// <paramref name="namedScope"/></summary>
 /// <param name="namedScope">The named scope to check</param>
 /// <returns>True if this alias can apply to the provided named scope; false
 /// otherwise</returns>
 public bool IsAliasFor(INamedScope namedScope)
 {
     if (this.IsNamespaceImport)
     {
         return(true);
     }
     return(false);
 }
 /// <summary>
 /// Small helper that works like <see cref="HashSet{T}.Add(T)"/> on the <see cref="INamedScope.Memory"/>
 /// dictionary.
 /// </summary>
 /// <param name="this">This scope.</param>
 /// <param name="key">The memory key. Must not be null or empty.</param>
 /// <returns>True if the key is new to the memory (and has been added), false if the key is already known.</returns>
 public static bool MemorizeOnce(this INamedScope @this, string key)
 {
     if (String.IsNullOrEmpty(key))
     {
         throw new ArgumentException("Key must not be null or white space.", nameof(key));
     }
     return(@this.Memory.TryAdd(key, null));
 }
示例#4
0
 private static bool TestEquality(INamedScope a, INamedScope b)
 {
     //Assert.AreEqual(a.Name, b.Name);
     ////Accessibility isn't undone right now, so don't check it
     ////Assert.AreEqual(a.Accessibility, b.Accessibility);
     //Assert.IsTrue(CollectionsAreEqual(a.ParentScopeCandidates, b.ParentScopeCandidates, NamedScopeUsesAreEqual));
     //Assert.IsTrue(NamedScopeUsesAreEqual(a.UnresolvedParentScopeInUse, b.UnresolvedParentScopeInUse));
     //return TestEquality((Scope)a, (Scope)b);
     return(a.Name == b.Name &&
            CollectionsAreEqual(a.ParentScopeCandidates, b.ParentScopeCandidates, NamedScopeUsesAreEqual) &&
            NamedScopeUsesAreEqual(a.UnresolvedParentScopeInUse, b.UnresolvedParentScopeInUse) &&
            TestEquality((Scope)a, (Scope)b));
 }
示例#5
0
        /// <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 INamedScope Merge(INamedScope otherScope)
        {
            NamespaceDefinition mergedScope = null;

            if (otherScope != null)
            {
                if (otherScope.CanBeMergedInto(this))
                {
                    mergedScope = new NamespaceDefinition(this);
                    mergedScope.AddFrom(otherScope);
                }
            }
            return(mergedScope);
        }
示例#6
0
        internal FunctionScopeImpl(CodeWorkspaceImpl ws, INamedScope parent)
            : base(ws, parent)
        {
            _funcs = new FunctionDefiner(true);
            INamedScope?p = parent;

            for (; ;)
            {
                if (p is ITypeScope t)
                {
                    EnclosingType = t;
                    break;
                }
                p = p.Parent;
                Debug.Assert(p != null, "We eventually reached a top level type.");
            }
        }
示例#7
0
        /// <summary>
        /// Merges this type 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 type definition from this and otherScope, or null if they couldn't be
        /// merged</returns>
        public override INamedScope Merge(INamedScope otherScope)
        {
            ITypeDefinition mergedScope = null;

            if (otherScope != null)
            {
                if (otherScope.CanBeMergedInto(this))
                {
                    mergedScope = new TypeDefinition(this);
                    mergedScope.AddFrom(otherScope);
                    if (mergedScope.Accessibility == AccessModifier.None)
                    {
                        mergedScope.Accessibility = otherScope.Accessibility;
                    }
                }
            }
            return(mergedScope as INamedScope);
        }
示例#8
0
        internal TypeScopeImpl(CodeWorkspaceImpl ws, INamedScope parent)
            : base(ws, parent)
        {
            UniqueId = ws.GetNextTypeScopeIdentifier();
            _funcs   = new FunctionDefiner(true);
            INamedScope?p = parent;

            for (; ;)
            {
                if (p is INamespaceScope ns)
                {
                    Namespace = ns;
                    break;
                }
                p = p.Parent;
                Debug.Assert(p != null, "We eventually reached the root namespace.");
            }
        }
示例#9
0
        /// <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(INamedScope childScope)
        {
            var scopeToAdd = childScope;

            if (childScope.UnresolvedParentScopeInUse == null && childScope.ParentScopeCandidates.Any())
            {
                var selectedScope = childScope.SelectUnresolvedScope();
                scopeToAdd = selectedScope.CreateScope();

                IScope latest = scopeToAdd, current;
                do
                {
                    current = latest;
                    latest  = current.ChildScopes.FirstOrDefault();
                } while(latest != null);

                current.AddChildScope(childScope);
            }
            base.AddChildScope(scopeToAdd);
        }
示例#10
0
        /// <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);
        }
示例#11
0
 public CodePart(INamedScope owner)
 {
     _owner = owner;
 }
示例#12
0
 internal FunctionScopeImpl(CodeWorkspaceImpl ws, INamedScope parent, FunctionDefinition def)
     : this(ws, parent)
 {
     _fDef = def;
     SetName(_fDef.Key);
 }
 /// <summary>
 /// Builds and returns the code.
 /// </summary>
 /// <param name="this">This scope.</param>
 /// <param name="closeScope">True to close the scope.</param>
 /// <returns>The source code of this named scope.</returns>
 public static string ToString(this INamedScope @this, bool closeScope)
 {
     return(@this.Build(new StringBuilder(), closeScope).ToString());
 }