public FixedSymbolTree(PackageSymbol package, FixedDictionary <Symbol, FixedSet <Symbol> > symbolChildren)
 {
     if (symbolChildren.Keys.Any(s => s.Package != package))
     {
         throw new ArgumentException("Children must be for this package", nameof(symbolChildren));
     }
     Package             = package;
     this.symbolChildren = symbolChildren;
 }
        public void With_different_type_are_not_equal()
        {
            var container = new PackageSymbol(Name("my.package"));
            var type1     = DataType("T1");
            var sym1      = Type(container, type1);
            var type2     = DataType("T2");
            var sym2      = Type(container, type2);

            Assert.NotEqual(sym1, sym2);
        }
Exemplo n.º 3
0
        void BuildCompletionData(PackageSymbol mpr)
        {
            foreach (var kv in mpr.Package.Packages)
            {
                CompletionDataGenerator.AddPackage(kv.Value.Name);
            }

            foreach (var kv in mpr.Package.Modules)
            {
                CompletionDataGenerator.AddModule(kv.Value);
            }
        }
Exemplo n.º 4
0
 public PackageSyntax(
     Name name,
     FixedSet <ICompilationUnitSyntax> compilationUnits,
     FixedDictionary <Name, PackageIL> references)
 {
     Symbol                = new PackageSymbol(name);
     SymbolTree            = new SymbolTreeBuilder(Symbol);
     CompilationUnits      = compilationUnits;
     AllEntityDeclarations = GetEntityDeclarations(CompilationUnits).ToFixedSet();
     References            = references;
     SymbolTrees           = new SymbolForest(Primitive.SymbolTree, SymbolTree, ReferencedPackages.Select(p => p.SymbolTree));
     Diagnostics           = new Diagnostics(CompilationUnits.SelectMany(cu => cu.Diagnostics));
 }
Exemplo n.º 5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BoundGlobalScope"/> class.
 /// </summary>
 /// <param name="previous">Previous compilation global scope.</param>
 /// <param name="package">The package for the current compilation.</param>
 /// <param name="diagnostics">Diagnostics for the current compilation.</param>
 /// <param name="imports">Imports in the current compilation.</param>
 /// <param name="functions">Functions in the current compilation.</param>
 /// <param name="variables">Variables in the current compilation.</param>
 /// <param name="statements">Statements in the current compilation.</param>
 public BoundGlobalScope(
     BoundGlobalScope previous,
     PackageSymbol package,
     ImmutableArray <Diagnostic> diagnostics,
     ImmutableArray <ImportSymbol> imports,
     ImmutableArray <FunctionSymbol> functions,
     ImmutableArray <VariableSymbol> variables,
     ImmutableArray <BoundStatement> statements)
 {
     Previous    = previous;
     Package     = package;
     Diagnostics = diagnostics;
     Imports     = imports;
     Functions   = functions;
     Variables   = variables;
     Statements  = statements;
 }
        private static FixedSymbolTree DefineIntrinsicSymbols()
        {
            var intrinsicsPackage = new PackageSymbol("intrinsics");
            var tree = new SymbolTreeBuilder(intrinsicsPackage);

            var intrinsicsNamespace = new NamespaceSymbol(intrinsicsPackage, "intrinsics");

            // params: length
            var memAllocate = new FunctionSymbol(intrinsicsNamespace, "mem_allocate", Params(DataType.Size), DataType.Size);

            tree.Add(memAllocate);

            // params: ptr
            var memDeallocate = new FunctionSymbol(intrinsicsNamespace, "mem_deallocate", Params(DataType.Size));

            tree.Add(memDeallocate);

            // params: from_ptr, to_ptr, length
            var memCopy = new FunctionSymbol(intrinsicsNamespace, "mem_copy", Params(DataType.Size, DataType.Size, DataType.Size));

            tree.Add(memCopy);

            // params: from_ptr, value
            var memSetByte = new FunctionSymbol(intrinsicsNamespace, "mem_set_byte", Params(DataType.Size, DataType.Byte));

            tree.Add(memSetByte);

            // params: ptr
            var memGetByte = new FunctionSymbol(intrinsicsNamespace, "mem_get_byte", Params(DataType.Size), DataType.Byte);

            tree.Add(memGetByte);

            // params: ptr, length
            var printUtf8 = new FunctionSymbol(intrinsicsNamespace, "print_utf8", Params(DataType.Size, DataType.Size));

            tree.Add(printUtf8);

            // params: ptr, length
            var readUtf8Line = new FunctionSymbol(intrinsicsNamespace, "read_utf8_line", Params(DataType.Size, DataType.Size), DataType.Size);

            tree.Add(readUtf8Line);

            return(tree.Build());
        }
Exemplo n.º 7
0
 protected override bool HandleItem(PackageSymbol pack)
 {
     // Packages were filtered in PrefilterSubnodes already..so just add & return
     matches_types.Add(pack);
     return true;
 }
Exemplo n.º 8
0
 public SymbolTreeBuilder(PackageSymbol package)
 {
     Package = package;
     symbolChildren.Add(package, new HashSet <Symbol>());
 }
Exemplo n.º 9
0
        /// <summary>
        /// The variable's or method's base type will be resolved (if auto type, the intializer's type will be taken).
        /// A class' base class will be searched.
        /// etc..
        /// </summary>
        public static AbstractType HandleNodeMatch(
            INode m,
            ResolutionContext ctxt,
            AbstractType resultBase = null,
            object typeBase         = null)
        {
            AbstractType ret = null;

            // See https://github.com/aBothe/Mono-D/issues/161
            int stkC;

            if (stackCalls == null)
            {
                stackCalls    = new Dictionary <INode, int>();
                stackCalls[m] = stkC = 1;
            }
            else if (stackCalls.TryGetValue(m, out stkC))
            {
                stackCalls[m] = ++stkC;
            }
            else
            {
                stackCalls[m] = stkC = 1;
            }

            /*
             * Pushing a new scope is only required if current scope cannot be found in the handled node's hierarchy.
             * Edit: No, it is required nearly every time because of nested type declarations - then, we do need the
             * current block scope.
             */
            bool popAfterwards;
            {
                var newScope = m is IBlockNode ? (IBlockNode)m : m.Parent as IBlockNode;
                popAfterwards = ctxt.ScopedBlock != newScope && newScope != null;
                if (popAfterwards)
                {
                    var options      = ctxt.CurrentContext.ContextDependentOptions;
                    var applyOptions = ctxt.ScopedBlockIsInNodeHierarchy(m);
                    ctxt.PushNewScope(newScope);
                    if (applyOptions)
                    {
                        ctxt.CurrentContext.ContextDependentOptions = options;
                    }
                }
            }

            var canResolveBase = ((ctxt.Options & ResolutionOptions.DontResolveBaseTypes) != ResolutionOptions.DontResolveBaseTypes) &&
                                 stkC < 10 && (m.Type == null || m.Type.ToString(false) != m.Name);

            // To support resolving type parameters to concrete types if the context allows this, introduce all deduced parameters to the current context
            if (resultBase is DSymbol)
            {
                ctxt.CurrentContext.IntroduceTemplateParameterTypes((DSymbol)resultBase);
            }

            var importSymbolNode = m as ImportSymbolNode;
            var variable         = m as DVariable;

            // Only import symbol aliases are allowed to search in the parse cache
            if (importSymbolNode != null)
            {
                ret = HandleImportSymbolMatch(importSymbolNode, ctxt);
            }
            else if (variable != null)
            {
                AbstractType bt = null;

                if (!(variable is EponymousTemplate))
                {
                    if (canResolveBase)
                    {
                        var bts = TypeDeclarationResolver.Resolve(variable.Type, ctxt);
                        ctxt.CheckForSingleResult(bts, variable.Type);

                        if (bts != null && bts.Length != 0)
                        {
                            bt = bts [0];
                        }

                        // For auto variables, use the initializer to get its type
                        else if (variable.Initializer != null)
                        {
                            bt = DResolver.StripMemberSymbols(Evaluation.EvaluateType(variable.Initializer, ctxt));
                        }

                        // Check if inside an foreach statement header
                        if (bt == null && ctxt.ScopedStatement != null)
                        {
                            bt = GetForeachIteratorType(variable, ctxt);
                        }
                    }

                    // Note: Also works for aliases! In this case, we simply try to resolve the aliased type, otherwise the variable's base type
                    ret = variable.IsAlias ?
                          new AliasedType(variable, bt, typeBase as ISyntaxRegion) as MemberSymbol :
                          new MemberSymbol(variable, bt, typeBase as ISyntaxRegion);
                }
                else
                {
                    ret = new EponymousTemplateType(variable as EponymousTemplate, GetInvisibleTypeParameters(variable, ctxt).AsReadOnly(), typeBase as ISyntaxRegion);
                }
            }
            else if (m is DMethod)
            {
                ret = new MemberSymbol(m as DNode, canResolveBase ? GetMethodReturnType(m as DMethod, ctxt) : null, typeBase as ISyntaxRegion);
            }
            else if (m is DClassLike)
            {
                ret = HandleClassLikeMatch(m as DClassLike, ctxt, typeBase, canResolveBase);
            }
            else if (m is DModule)
            {
                var mod = (DModule)m;
                if (typeBase != null && typeBase.ToString() != mod.ModuleName)
                {
                    var pack = ctxt.ParseCache.LookupPackage(typeBase.ToString()).FirstOrDefault();
                    if (pack != null)
                    {
                        ret = new PackageSymbol(pack, typeBase as ISyntaxRegion);
                    }
                }
                else
                {
                    ret = new ModuleSymbol(m as DModule, typeBase as ISyntaxRegion);
                }
            }
            else if (m is DEnum)
            {
                ret = new EnumType((DEnum)m, typeBase as ISyntaxRegion);
            }
            else if (m is TemplateParameter.Node)
            {
                //ResolveResult[] templateParameterType = null;

                //TODO: Resolve the specialization type
                //var templateParameterType = TemplateInstanceHandler.ResolveTypeSpecialization(tmp, ctxt);
                ret = new TemplateParameterSymbol((m as TemplateParameter.Node).TemplateParameter, null, typeBase as ISyntaxRegion);
            }
            else if (m is NamedTemplateMixinNode)
            {
                var tmxNode = m as NamedTemplateMixinNode;
                ret = new MemberSymbol(tmxNode, canResolveBase ? ResolveSingle(tmxNode.Type, ctxt) : null, typeBase as ISyntaxRegion);
            }

            if (popAfterwards)
            {
                ctxt.Pop();
            }
            else if (resultBase is DSymbol)
            {
                ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals((DSymbol)resultBase);
            }

            if (stkC == 1)
            {
                stackCalls.Remove(m);
            }
            else
            {
                stackCalls[m] = stkC - 1;
            }

            return(ret);
        }
		/// <summary>
		/// The variable's or method's base type will be resolved (if auto type, the intializer's type will be taken).
		/// A class' base class will be searched.
		/// etc..
		/// </summary>
		public static AbstractType HandleNodeMatch(
			INode m,
			ResolutionContext ctxt,
			AbstractType resultBase = null,
			object typeBase = null)
		{
			AbstractType ret = null;

			// See https://github.com/aBothe/Mono-D/issues/161
			int stkC;

			if (stackCalls == null)
			{
				stackCalls = new Dictionary<INode, int>();
				stackCalls[m] = stkC = 1;
			}
			else if (stackCalls.TryGetValue(m, out stkC))
				stackCalls[m] = ++stkC;
			else
				stackCalls[m] = stkC = 1;
			/*
			 * Pushing a new scope is only required if current scope cannot be found in the handled node's hierarchy.
			 * Edit: No, it is required nearly every time because of nested type declarations - then, we do need the 
			 * current block scope.
			 */
			bool popAfterwards;
			{
				var newScope = m is IBlockNode ? (IBlockNode)m : m.Parent as IBlockNode;
				popAfterwards = ctxt.ScopedBlock != newScope && newScope != null;
				if (popAfterwards) {
					var options = ctxt.CurrentContext.ContextDependentOptions;
					var applyOptions = ctxt.ScopedBlockIsInNodeHierarchy (m);
					ctxt.PushNewScope (newScope);
					if (applyOptions)
						ctxt.CurrentContext.ContextDependentOptions = options;
				}
			}

			var canResolveBase = ((ctxt.Options & ResolutionOptions.DontResolveBaseTypes) != ResolutionOptions.DontResolveBaseTypes) && 
			                     stkC < 10 && (m.Type == null || m.Type.ToString(false) != m.Name);
			
			// To support resolving type parameters to concrete types if the context allows this, introduce all deduced parameters to the current context
			if (resultBase is DSymbol)
				ctxt.CurrentContext.IntroduceTemplateParameterTypes((DSymbol)resultBase);

			var importSymbolNode = m as ImportSymbolNode;
			var variable = m as DVariable;

			// Only import symbol aliases are allowed to search in the parse cache
			if (importSymbolNode != null)
				ret = HandleImportSymbolMatch (importSymbolNode,ctxt);
			else if (variable != null)
			{
				AbstractType bt = null;

				if (!(variable is EponymousTemplate)) {
					if (canResolveBase) {
						var bts = TypeDeclarationResolver.Resolve (variable.Type, ctxt);
						ctxt.CheckForSingleResult (bts, variable.Type);

						if (bts != null && bts.Length != 0)
							bt = bts [0];

					// For auto variables, use the initializer to get its type
					else if (variable.Initializer != null) {
							bt = DResolver.StripMemberSymbols (Evaluation.EvaluateType (variable.Initializer, ctxt));
						}

						// Check if inside an foreach statement header
						if (bt == null && ctxt.ScopedStatement != null)
							bt = GetForeachIteratorType (variable, ctxt);
					}

					// Note: Also works for aliases! In this case, we simply try to resolve the aliased type, otherwise the variable's base type
					ret = variable.IsAlias ?
					new AliasedType (variable, bt, typeBase as ISyntaxRegion) as MemberSymbol :
					new MemberSymbol (variable, bt, typeBase as ISyntaxRegion);
				} else
					ret = new EponymousTemplateType (variable as EponymousTemplate, GetInvisibleTypeParameters(variable, ctxt).AsReadOnly(), typeBase as ISyntaxRegion);
			}
			else if (m is DMethod)
			{
				ret = new MemberSymbol(m as DNode,canResolveBase ? GetMethodReturnType(m as DMethod, ctxt) : null, typeBase as ISyntaxRegion);
			}
			else if (m is DClassLike)
				ret = HandleClassLikeMatch (m as DClassLike, ctxt, typeBase, canResolveBase);
			else if (m is DModule)
			{
				var mod = (DModule)m;
				if (typeBase != null && typeBase.ToString() != mod.ModuleName)
				{
					var pack = ctxt.ParseCache.LookupPackage(typeBase.ToString()).FirstOrDefault();
					if (pack != null)
						ret = new PackageSymbol(pack, typeBase as ISyntaxRegion);
				}
				else
					ret = new ModuleSymbol(m as DModule, typeBase as ISyntaxRegion);
			}
			else if (m is DEnum)
				ret = new EnumType((DEnum)m, typeBase as ISyntaxRegion);
			else if (m is TemplateParameter.Node)
			{
				//ResolveResult[] templateParameterType = null;

				//TODO: Resolve the specialization type
				//var templateParameterType = TemplateInstanceHandler.ResolveTypeSpecialization(tmp, ctxt);
				ret = new TemplateParameterSymbol((m as TemplateParameter.Node).TemplateParameter, null, typeBase as ISyntaxRegion);
			}
			else if(m is NamedTemplateMixinNode)
			{
				var tmxNode = m as NamedTemplateMixinNode;
				ret = new MemberSymbol(tmxNode, canResolveBase ? ResolveSingle(tmxNode.Type, ctxt) : null, typeBase as ISyntaxRegion);
			}

			if (popAfterwards)
				ctxt.Pop();
			else if (resultBase is DSymbol)
				ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals((DSymbol)resultBase);

			if (stkC == 1)
				stackCalls.Remove(m);
			else
				stackCalls[m] = stkC-1;

			return ret;
		}
Exemplo n.º 11
0
		protected abstract bool HandleItem(PackageSymbol pack);
Exemplo n.º 12
0
 protected override bool HandleItem(PackageSymbol pack)
 {
     // Packages were filtered in PrefilterSubnodes already..so just add & return
     matches_types.Add(pack);
     return(true);
 }
Exemplo n.º 13
0
		protected override void HandleItem (PackageSymbol pack)
		{
			// Packages were filtered in PrefilterSubnodes already..so just add & return
			matches_types.Add (pack);
			stopEnumeration = true;
		}
Exemplo n.º 14
0
		protected override bool HandleItem (PackageSymbol pack)
		{
			return false;
		}
Exemplo n.º 15
0
 protected override bool HandleItem(PackageSymbol pack)
 {
     gen.AddPackage(pack.Package.Name);
     return(false);
 }
Exemplo n.º 16
0
        /// <summary>
        /// The variable's or method's base type will be resolved (if auto type, the intializer's type will be taken).
        /// A class' base class will be searched.
        /// etc..
        /// </summary>
        public static AbstractType HandleNodeMatch(
			INode m,
			ResolverContextStack ctxt,
			AbstractType resultBase = null,
			object typeBase = null)
        {
            stackNum_HandleNodeMatch++;

            bool popAfterwards = m.Parent != ctxt.ScopedBlock && m.Parent is IBlockNode;
            if (popAfterwards)
                ctxt.PushNewScope((IBlockNode)m.Parent);

            //HACK: Really dirty stack overflow prevention via manually counting call depth
            var canResolveBaseGenerally = stackNum_HandleNodeMatch < 6;

            var DoResolveBaseType = canResolveBaseGenerally &&
                !ctxt.Options.HasFlag(ResolutionOptions.DontResolveBaseClasses) &&
                (m.Type == null || m.Type.ToString(false) != m.Name);

            AbstractType ret = null;

            // To support resolving type parameters to concrete types if the context allows this, introduce all deduced parameters to the current context
            if (canResolveBaseGenerally && resultBase is DSymbol)
                ctxt.CurrentContext.IntroduceTemplateParameterTypes((DSymbol)resultBase);

            // Only import symbol aliases are allowed to search in the parse cache
            if (m is ImportSymbolAlias)
            {
                var isa = (ImportSymbolAlias)m;

                if (isa.IsModuleAlias ? isa.Type != null : isa.Type.InnerDeclaration != null)
                {
                    var mods = new List<DModule>();
                    var td=isa.IsModuleAlias ? isa.Type : isa.Type.InnerDeclaration;
                    foreach (var mod in ctxt.ParseCache.LookupModuleName(td.ToString()))
                        mods.Add(mod as DModule);

                    if(mods.Count == 0)
                            ctxt.LogError(new NothingFoundError(isa.Type));
                    else if(mods.Count > 1)
                    {
                        var m__=new List<ISemantic>();

                        foreach(var mod in mods)
             							m__.Add(new ModuleSymbol(mod, isa.Type));

                        ctxt.LogError(new AmbiguityError(isa.Type,m__));
                    }

                    var bt=mods.Count != 0 ? (AbstractType)new ModuleSymbol(mods[0], td) : null;

                    //TODO: Is this correct behaviour?
                    if (!isa.IsModuleAlias){
                        var furtherId = ResolveFurtherTypeIdentifier(isa.Type.ToString(false), new[]{ bt }, ctxt, isa.Type);

                        ctxt.CheckForSingleResult(furtherId, isa.Type);

                        if (furtherId != null && furtherId.Length != 0)
                            bt = furtherId[0];
                        else
                            bt = null;
                    }

                    ret = new AliasedType(isa, bt, isa.Type);
                }
            }
            else if (m is DVariable)
            {
                var v = (DVariable)m;
                AbstractType bt = null;

                if (DoResolveBaseType)
                {
                    var bts = TypeDeclarationResolver.Resolve(v.Type, ctxt);

                    if (bts != null && bts.Length != 0 && ctxt.CheckForSingleResult(bts, v.Type))
                        bt = bts[0];

                    // For auto variables, use the initializer to get its type
                    else if (v.Initializer != null)
                        bt = ExpressionSemantics.Evaluation.EvaluateType(v.Initializer, ctxt);

                    // Check if inside an foreach statement header
                    if (bt == null && ctxt.ScopedStatement != null)
                        bt = GetForeachIteratorType(v, ctxt);
                }

                // Note: Also works for aliases! In this case, we simply try to resolve the aliased type, otherwise the variable's base type
                ret=v.IsAlias ?
                    (DSymbol)new AliasedType(v, bt, typeBase as ISyntaxRegion) :
                    new MemberSymbol(v, bt, typeBase as ISyntaxRegion);
            }
            else if (m is DMethod)
            {
                ret = new MemberSymbol((DNode)m,
                    DoResolveBaseType ? GetMethodReturnType((DMethod)m, ctxt) : null
                    , typeBase as ISyntaxRegion);
            }
            else if (m is DClassLike)
            {
                UserDefinedType udt = null;
                var dc=(DClassLike)m;

                switch (dc.ClassType)
                {
                    case DTokens.Struct:
                        udt = new StructType(dc, typeBase as ISyntaxRegion);
                        break;
                    case DTokens.Union:
                        udt = new UnionType(dc, typeBase as ISyntaxRegion);
                        break;
                    case DTokens.Class:
                        udt = new ClassType(dc, typeBase as ISyntaxRegion, null);
                        break;
                    case DTokens.Template:
                        udt = new TemplateType(dc, typeBase as ISyntaxRegion);
                        break;
                    case DTokens.Interface:
                        udt = new InterfaceType(dc, typeBase as ISyntaxRegion);
                        break;
                    default:
                        ctxt.LogError(new ResolutionError(m, "Unknown type ("+DTokens.GetTokenString(dc.ClassType)+")"));
                        break;
                }

                if (canResolveBaseGenerally && !ctxt.Options.HasFlag(ResolutionOptions.DontResolveBaseClasses))
                    ret = DResolver.ResolveBaseClasses(udt, ctxt);
                else
                    ret = udt;
            }
            else if (m is IAbstractSyntaxTree)
            {
                var mod = (IAbstractSyntaxTree)m;
                if (typeBase != null && typeBase.ToString() != mod.ModuleName)
                {
                    var pack = ctxt.ParseCache.LookupPackage(typeBase.ToString()).First();
                    if (pack != null)
                        ret = new PackageSymbol(pack, typeBase as ISyntaxRegion);
                }
                else
                    ret = new ModuleSymbol(m as DModule, typeBase as ISyntaxRegion);
            }
            else if (m is DEnum)
                ret = new EnumType((DEnum)m, typeBase as ISyntaxRegion);
            else if (m is TemplateParameterNode)
            {
                var tmp = ((TemplateParameterNode)m).TemplateParameter;

                //ResolveResult[] templateParameterType = null;

                //TODO: Resolve the specialization type
                //var templateParameterType = TemplateInstanceHandler.ResolveTypeSpecialization(tmp, ctxt);

                ret = new MemberSymbol((DNode)m, null, typeBase as ISyntaxRegion);
            }

            if (canResolveBaseGenerally && resultBase is DSymbol)
                ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals((DSymbol)resultBase);

            if (popAfterwards)
                ctxt.Pop();

            stackNum_HandleNodeMatch--;
            return ret;
        }
Exemplo n.º 17
0
 public ISymbolValue VisitPackageSymbol(PackageSymbol t)
 {
     throw new NotImplementedException();
 }
 public PackagesScope(PackageSymbol currentPackage, FixedDictionary <Name, PackageSymbol> packageAliases)
 {
     CurrentPackage      = currentPackage;
     this.packageAliases = packageAliases;
 }
Exemplo n.º 19
0
 protected override bool HandleItem(PackageSymbol pack)
 {
     return(false);
 }
Exemplo n.º 20
0
 public ulong VisitPackageSymbol(PackageSymbol t)
 {
     return(1001977);
 }
Exemplo n.º 21
0
 protected abstract bool HandleItem(PackageSymbol pack);
Exemplo n.º 22
0
        /// <summary>
        /// The variable's or method's base type will be resolved (if auto type, the intializer's type will be taken).
        /// A class' base class will be searched.
        /// etc..
        /// </summary>
        public static AbstractType HandleNodeMatch(
            INode m,
            ResolverContextStack ctxt,
            AbstractType resultBase = null,
            object typeBase         = null)
        {
            stackNum_HandleNodeMatch++;

            /*
             * Pushing a new scope is only required if current scope cannot be found in the handled node's hierarchy.
             */
            bool popAfterwards = !ctxt.NodeIsInCurrentScopeHierarchy(m);

            if (popAfterwards)
            {
                ctxt.PushNewScope(m is IBlockNode ? (IBlockNode)m : m.Parent as IBlockNode);
            }



            //HACK: Really dirty stack overflow prevention via manually counting call depth
            var canResolveBaseGenerally = stackNum_HandleNodeMatch < 6;



            var DoResolveBaseType = canResolveBaseGenerally &&
                                    !ctxt.Options.HasFlag(ResolutionOptions.DontResolveBaseClasses) &&
                                    (m.Type == null || m.Type.ToString(false) != m.Name);

            AbstractType ret = null;

            // To support resolving type parameters to concrete types if the context allows this, introduce all deduced parameters to the current context
            if (canResolveBaseGenerally && resultBase is DSymbol)
            {
                ctxt.CurrentContext.IntroduceTemplateParameterTypes((DSymbol)resultBase);
            }

            // Only import symbol aliases are allowed to search in the parse cache
            if (m is ImportSymbolAlias)
            {
                var isa = (ImportSymbolAlias)m;

                if (isa.IsModuleAlias ? isa.Type != null : isa.Type.InnerDeclaration != null)
                {
                    var mods = new List <DModule>();
                    var td   = isa.IsModuleAlias ? isa.Type : isa.Type.InnerDeclaration;
                    foreach (var mod in ctxt.ParseCache.LookupModuleName(td.ToString()))
                    {
                        mods.Add(mod as DModule);
                    }

                    if (mods.Count == 0)
                    {
                        ctxt.LogError(new NothingFoundError(isa.Type));
                    }
                    else if (mods.Count > 1)
                    {
                        var m__ = new List <ISemantic>();

                        foreach (var mod in mods)
                        {
                            m__.Add(new ModuleSymbol(mod, isa.Type));
                        }

                        ctxt.LogError(new AmbiguityError(isa.Type, m__));
                    }

                    var bt = mods.Count != 0 ? (AbstractType) new ModuleSymbol(mods[0], td) : null;

                    //TODO: Is this correct behaviour?
                    if (!isa.IsModuleAlias)
                    {
                        var furtherId = ResolveFurtherTypeIdentifier(isa.Type.ToString(false), new[] { bt }, ctxt, isa.Type);

                        ctxt.CheckForSingleResult(furtherId, isa.Type);

                        if (furtherId != null && furtherId.Length != 0)
                        {
                            bt = furtherId[0];
                        }
                        else
                        {
                            bt = null;
                        }
                    }

                    ret = new AliasedType(isa, bt, isa.Type);
                }
            }
            else if (m is DVariable)
            {
                var          v  = (DVariable)m;
                AbstractType bt = null;

                if (DoResolveBaseType)
                {
                    var bts = TypeDeclarationResolver.Resolve(v.Type, ctxt);

                    if (bts != null && bts.Length != 0 && ctxt.CheckForSingleResult(bts, v.Type))
                    {
                        bt = bts[0];
                    }

                    // For auto variables, use the initializer to get its type
                    else if (v.Initializer != null)
                    {
                        bt = ExpressionSemantics.Evaluation.EvaluateType(v.Initializer, ctxt);
                    }

                    // Check if inside an foreach statement header
                    if (bt == null && ctxt.ScopedStatement != null)
                    {
                        bt = GetForeachIteratorType(v, ctxt);
                    }
                }

                // Note: Also works for aliases! In this case, we simply try to resolve the aliased type, otherwise the variable's base type
                ret = v.IsAlias ?
                      (DSymbol) new AliasedType(v, bt, typeBase as ISyntaxRegion) :
                      new MemberSymbol(v, bt, typeBase as ISyntaxRegion);
            }
            else if (m is DMethod)
            {
                ret = new MemberSymbol((DNode)m,
                                       DoResolveBaseType ? GetMethodReturnType((DMethod)m, ctxt) : null
                                       , typeBase as ISyntaxRegion);
            }
            else if (m is DClassLike)
            {
                UserDefinedType udt = null;
                var             dc  = (DClassLike)m;

                var invisibleTypeParams = new Dictionary <string, TemplateParameterSymbol>();

                /*
                 * Add 'superior' template parameters to the current symbol because the parameters
                 * might be re-used in the nested class.
                 */
                var tStk = new Stack <ResolverContext>();
                do
                {
                    var curCtxt = ctxt.Pop();
                    tStk.Push(curCtxt);
                    foreach (var kv in curCtxt.DeducedTemplateParameters)
                    {
                        if (!dc.ContainsTemplateParameter(kv.Key) &&
                            !invisibleTypeParams.ContainsKey(kv.Key))
                        {
                            invisibleTypeParams.Add(kv.Key, kv.Value);
                        }
                    }
                } while (ctxt.PrevContextIsInSameHierarchy);

                while (tStk.Count != 0)
                {
                    ctxt.Push(tStk.Pop());
                }

                switch (dc.ClassType)
                {
                case DTokens.Struct:
                    ret = new StructType(dc, typeBase as ISyntaxRegion, invisibleTypeParams);
                    break;

                case DTokens.Union:
                    ret = new UnionType(dc, typeBase as ISyntaxRegion, invisibleTypeParams);
                    break;

                case DTokens.Class:
                    udt = new ClassType(dc, typeBase as ISyntaxRegion, null, null, invisibleTypeParams);
                    break;

                case DTokens.Interface:
                    udt = new InterfaceType(dc, typeBase as ISyntaxRegion, null, invisibleTypeParams);
                    break;

                case DTokens.Template:
                    ret = new TemplateType(dc, typeBase as ISyntaxRegion, invisibleTypeParams);
                    break;

                default:
                    ctxt.LogError(new ResolutionError(m, "Unknown type (" + DTokens.GetTokenString(dc.ClassType) + ")"));
                    break;
                }

                if (dc.ClassType == DTokens.Class || dc.ClassType == DTokens.Interface)
                {
                    if (canResolveBaseGenerally &&
                        !ctxt.Options.HasFlag(ResolutionOptions.DontResolveBaseClasses))
                    {
                        ret = DResolver.ResolveBaseClasses(udt, ctxt);
                    }
                    else
                    {
                        ret = udt;
                    }
                }
            }
            else if (m is IAbstractSyntaxTree)
            {
                var mod = (IAbstractSyntaxTree)m;
                if (typeBase != null && typeBase.ToString() != mod.ModuleName)
                {
                    var pack = ctxt.ParseCache.LookupPackage(typeBase.ToString()).First();
                    if (pack != null)
                    {
                        ret = new PackageSymbol(pack, typeBase as ISyntaxRegion);
                    }
                }
                else
                {
                    ret = new ModuleSymbol(m as DModule, typeBase as ISyntaxRegion);
                }
            }
            else if (m is DEnum)
            {
                ret = new EnumType((DEnum)m, typeBase as ISyntaxRegion);
            }
            else if (m is TemplateParameterNode)
            {
                //ResolveResult[] templateParameterType = null;

                //TODO: Resolve the specialization type
                //var templateParameterType = TemplateInstanceHandler.ResolveTypeSpecialization(tmp, ctxt);
                ret = new TemplateParameterSymbol((TemplateParameterNode)m, null, typeBase as ISyntaxRegion);
            }

            if (canResolveBaseGenerally && resultBase is DSymbol)
            {
                ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals((DSymbol)resultBase);
            }

            if (popAfterwards)
            {
                ctxt.Pop();
            }

            stackNum_HandleNodeMatch--;
            return(ret);
        }
Exemplo n.º 23
0
 public ISymbolValue VisitPackageSymbol(PackageSymbol t)
 {
     return(new TypeValue(t));
 }