コード例 #1
0
        AbstractType HandleAccessExpressions(PostfixExpression_Access acc, ResolverContextStack ctxt)
        {
            AbstractType pfType = null;

            if (acc.PostfixForeExpression is PostfixExpression_Access)
            {
                pfType = HandleAccessExpressions((PostfixExpression_Access)acc.PostfixForeExpression, ctxt);
            }
            else
            {
                pfType = DResolver.StripAliasSymbol(Evaluation.EvaluateType(acc.PostfixForeExpression, ctxt));

                if (acc.PostfixForeExpression is IdentifierExpression ||
                    acc.PostfixForeExpression is TemplateInstanceExpression ||
                    acc.PostfixForeExpression is PostfixExpression_Access)
                {
                    HandleResult(acc.PostfixForeExpression, pfType);
                }
            }

            bool ufcs            = false;
            var  accessedMembers = Evaluation.GetAccessedOverloads(acc, ctxt, out ufcs, pfType);

            ctxt.CheckForSingleResult(accessedMembers, acc);

            if (accessedMembers != null && accessedMembers.Length != 0)
            {
                HandleResult(acc, accessedMembers[0]);
                return(accessedMembers[0]);
            }

            return(null);
        }
コード例 #2
0
        public static AssocArrayType Resolve(ArrayDecl ad, ResolverContextStack ctxt)
        {
            var valueTypes = Resolve(ad.ValueType, ctxt);

            ctxt.CheckForSingleResult(valueTypes, ad);

            AbstractType valueType        = null;
            AbstractType keyType          = null;
            int          fixedArrayLength = -1;

            if (valueTypes == null || valueTypes.Length == 0)
            {
                return(null);
            }
            valueType = valueTypes[0];

            ISymbolValue val;

            keyType = ResolveKey(ad, out fixedArrayLength, out val, ctxt);


            if (keyType == null || (keyType is PrimitiveType && ((PrimitiveType)keyType).TypeToken == DTokens.Int))
            {
                return(fixedArrayLength == -1 ?
                       new ArrayType(valueType, ad) :
                       new ArrayType(valueType, fixedArrayLength, ad));
            }

            return(new AssocArrayType(valueType, keyType, ad));
        }
コード例 #3
0
        public static AbstractType ResolveSingle(IdentifierDeclaration id, ResolverContextStack ctxt, AbstractType[] resultBases = null, bool filterForTemplateArgs = true)
        {
            var r = Resolve(id, ctxt, resultBases, filterForTemplateArgs);

            ctxt.CheckForSingleResult(r, id);

            return(r != null && r.Length != 0 ? r[0] : null);
        }
コード例 #4
0
        public static AbstractType getStringType(ResolverContextStack ctxt)
        {
            var str = new IdentifierDeclaration("string");
            var sType = TypeDeclarationResolver.Resolve(str, ctxt);
            ctxt.CheckForSingleResult(sType, str);

            return sType != null && sType.Length != 0 ? sType[0] : null;
        }
コード例 #5
0
        public static AbstractType ResolveSingle(string id, ResolverContextStack ctxt, object idObject, bool ModuleScope = false)
        {
            var r = ResolveIdentifier(id, ctxt, idObject, ModuleScope);

            ctxt.CheckForSingleResult(r, idObject as ISyntaxRegion);

            return(r != null && r.Length != 0 ? r[0] : null);
        }
コード例 #6
0
        public static AbstractType getStringType(ResolverContextStack ctxt)
        {
            var str   = new IdentifierDeclaration("string");
            var sType = TypeDeclarationResolver.Resolve(str, ctxt);

            ctxt.CheckForSingleResult(sType, str);

            return(sType != null && sType.Length != 0 ? sType[0] : null);
        }
コード例 #7
0
        public static List <ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolverContextStack ctxt)
        {
            // Resolve given argument expressions
            var templateArguments = new List <ISemantic>();

            if (tix != null && tix.Arguments != null)
            {
                foreach (var arg in tix.Arguments)
                {
                    if (arg is TypeDeclarationExpression)
                    {
                        var tde = (TypeDeclarationExpression)arg;

                        var res = TypeDeclarationResolver.Resolve(tde.Declaration, ctxt);

                        if (ctxt.CheckForSingleResult(res, tde.Declaration) || res != null)
                        {
                            var mr = res[0] as MemberSymbol;
                            if (mr != null && mr.Definition is DVariable)
                            {
                                var dv = (DVariable)mr.Definition;

                                if (dv.IsAlias || dv.Initializer == null)
                                {
                                    templateArguments.Add(mr);
                                    continue;
                                }

                                ISemantic eval = null;

                                try
                                {
                                    eval = new StandardValueProvider(ctxt)[dv];
                                }
                                catch (System.Exception ee)                                // Should be a non-const-expression error here only
                                {
                                    ctxt.LogError(dv.Initializer, ee.Message);
                                }

                                templateArguments.Add(eval == null ? (ISemantic)mr : eval);
                            }
                            else
                            {
                                templateArguments.Add(res[0]);
                            }
                        }
                    }
                    else
                    {
                        templateArguments.Add(Evaluation.EvaluateValue(arg, ctxt));
                    }
                }
            }

            return(templateArguments);
        }
コード例 #8
0
        public static DelegateType Resolve(DelegateDeclaration dg, ResolverContextStack ctxt)
        {
            var returnTypes = Resolve(dg.ReturnType, ctxt);

            ctxt.CheckForSingleResult(returnTypes, dg.ReturnType);

            if (returnTypes != null && returnTypes.Length != 0)
            {
                return(new DelegateType(returnTypes[0], dg));                // Parameter types will be resolved later on
            }
            return(null);
        }
コード例 #9
0
        public static PointerType Resolve(PointerDecl pd, ResolverContextStack ctxt)
        {
            var ptrBaseTypes = Resolve(pd.InnerDeclaration, ctxt);

            ctxt.CheckForSingleResult(ptrBaseTypes, pd);

            if (ptrBaseTypes == null || ptrBaseTypes.Length == 0)
            {
                return(null);
            }

            return(new PointerType(ptrBaseTypes[0], pd));
        }
コード例 #10
0
        public static AbstractType Resolve(MemberFunctionAttributeDecl attrDecl, ResolverContextStack ctxt)
        {
            if (attrDecl != null)
            {
                var ret = Resolve(attrDecl.InnerType, ctxt);

                ctxt.CheckForSingleResult(ret, attrDecl.InnerType);

                if (ret != null && ret.Length != 0 && ret[0] != null)
                {
                    ret[0].Modifier = attrDecl.Modifier;
                    return(ret[0]);
                }
            }
            return(null);
        }
コード例 #11
0
        public static AbstractType GetMethodReturnType(DelegateType dg, ResolverContextStack ctxt)
        {
            if (dg == null || ctxt == null)
            {
                return(null);
            }

            if (dg.IsFunctionLiteral)
            {
                return(GetMethodReturnType(((FunctionLiteral)dg.DeclarationOrExpressionBase).AnonymousMethod, ctxt));
            }
            else
            {
                var rt = ((DelegateDeclaration)dg.DeclarationOrExpressionBase).ReturnType;
                var r  = Resolve(rt, ctxt);

                ctxt.CheckForSingleResult(r, rt);

                return(r[0]);
            }
        }
コード例 #12
0
        /// <summary>
        /// Tries to resolve a static property's name.
        /// Returns a result describing the theoretical member (".init"-%gt;MemberResult; ".typeof"-&gt;TypeResult etc).
        /// Returns null if nothing was found.
        /// </summary>
        /// <param name="InitialResult"></param>
        /// <returns></returns>
        public static MemberSymbol TryResolveStaticProperties(
			ISemantic InitialResult, 
			string propertyIdentifier, 
			ResolverContextStack ctxt = null, 
			bool Evaluate = false,
			IdentifierDeclaration idContainter = null)
        {
            // If a pointer'ed type is given, take its base type
            if (InitialResult is PointerType)
                InitialResult = ((PointerType)InitialResult).Base;

            if (InitialResult == null || InitialResult is ModuleSymbol)
                return null;

            INode relatedNode = null;

            if (InitialResult is DSymbol)
                relatedNode = ((DSymbol)InitialResult).Definition;

            #region init
            if (propertyIdentifier == "init")
            {
                var prop_Init = new DVariable
                {
                    Name = "init",
                    Description = "Initializer"
                };

                if (relatedNode != null)
                {
                    if (!(relatedNode is DVariable))
                    {
                        prop_Init.Parent = relatedNode.Parent;
                        prop_Init.Type = new IdentifierDeclaration(relatedNode.Name);
                    }
                    else
                    {
                        prop_Init.Parent = relatedNode;
                        prop_Init.Initializer = (relatedNode as DVariable).Initializer;
                        prop_Init.Type = relatedNode.Type;
                    }
                }

                return new MemberSymbol(prop_Init, DResolver.StripAliasSymbol(AbstractType.Get(InitialResult)), idContainter);
            }
            #endregion

            #region sizeof
            if (propertyIdentifier == "sizeof")
                return new MemberSymbol(new DVariable
                    {
                        Name = "sizeof",
                        Type = new DTokenDeclaration(DTokens.Int),
                        Initializer = new IdentifierExpression(4),
                        Description = "Size in bytes (equivalent to C's sizeof(type))"
                    }, new PrimitiveType(DTokens.Int), idContainter);
            #endregion

            #region alignof
            if (propertyIdentifier == "alignof")
                return new MemberSymbol(new DVariable
                    {
                        Name = "alignof",
                        Type = new DTokenDeclaration(DTokens.Int),
                        Description = "Alignment size"
                    }, new PrimitiveType(DTokens.Int),idContainter);
            #endregion

            #region mangleof
            if (propertyIdentifier == "mangleof")
                return new MemberSymbol(new DVariable
                    {
                        Name = "mangleof",
                        Type = new IdentifierDeclaration("string"),
                        Description = "String representing the ‘mangled’ representation of the type"
                    }, getStringType(ctxt) , idContainter);
            #endregion

            #region stringof
            if (propertyIdentifier == "stringof")
                return new MemberSymbol(new DVariable
                    {
                        Name = "stringof",
                        Type = new IdentifierDeclaration("string"),
                        Description = "String representing the source representation of the type"
                    }, getStringType(ctxt), idContainter);
            #endregion

            #region classinfo
            else if (propertyIdentifier == "classinfo")
            {
                var tr = DResolver.StripMemberSymbols(AbstractType.Get(InitialResult)) as TemplateIntermediateType;

                if (tr is ClassType || tr is InterfaceType)
                {
                    var ci=new IdentifierDeclaration("TypeInfo_Class")
                    {
                        InnerDeclaration = new IdentifierDeclaration("object"),
                        ExpressesVariableAccess = true,
                    };

                    var ti = TypeDeclarationResolver.Resolve(ci, ctxt);

                    ctxt.CheckForSingleResult(ti, ci);

                    return new MemberSymbol(new DVariable { Name = "classinfo", Type = ci }, ti!=null && ti.Length!=0?ti[0]:null, idContainter);
                }
            }
            #endregion

            //TODO: Resolve the types of type-specific properties (floats, ints, arrays, assocarrays etc.)

            return null;
        }
コード例 #13
0
        public static AbstractType GetMethodReturnType(DelegateType dg, ResolverContextStack ctxt)
        {
            if (dg == null || ctxt == null)
                return null;

            if (dg.IsFunctionLiteral)
                return GetMethodReturnType(((FunctionLiteral)dg.DeclarationOrExpressionBase).AnonymousMethod, ctxt);
            else
            {
                var rt=((DelegateDeclaration)dg.DeclarationOrExpressionBase).ReturnType;
                var r = Resolve(rt, ctxt);

                ctxt.CheckForSingleResult(r,rt);

                return r[0];
            }
        }
コード例 #14
0
        public static AbstractType GetMethodReturnType(DMethod method, ResolverContextStack ctxt)
        {
            if (ctxt!=null && ctxt.Options.HasFlag(ResolutionOptions.DontResolveBaseTypes))
                return null;

            /*
             * If a method's type equals null, assume that it's an 'auto' function..
             * 1) Search for a return statement
             * 2) Resolve the returned expression
             * 3) Use that one as the method's type
             */

            if (method.Type != null)
            {
                var returnType = TypeDeclarationResolver.Resolve(method.Type, ctxt);

                if (ctxt.CheckForSingleResult(returnType, method.Type))
                    return returnType[0];
            }
            else if (method.Body != null)
            {
                ReturnStatement returnStmt = null;
                var list = new List<IStatement> { method.Body };
                var list2 = new List<IStatement>();

                bool foundMatch = false;
                while (!foundMatch && list.Count > 0)
                {
                    foreach (var stmt in list)
                    {
                        if (stmt is ReturnStatement)
                        {
                            returnStmt = stmt as ReturnStatement;

                            if (!(returnStmt.ReturnExpression is TokenExpression) ||
                                (returnStmt.ReturnExpression as TokenExpression).Token != DTokens.Null)
                            {
                                foundMatch = true;
                                break;
                            }
                        }

                        if (stmt is StatementContainingStatement)
                            list2.AddRange((stmt as StatementContainingStatement).SubStatements);
                    }

                    list = list2;
                    list2 = new List<IStatement>();
                }

                if (returnStmt != null && returnStmt.ReturnExpression != null)
                {
                    ctxt.PushNewScope(method);

                    var t= Evaluation.EvaluateType(returnStmt.ReturnExpression, ctxt);

                    ctxt.Pop();

                    return t;
                }
            }

            return null;
        }
コード例 #15
0
        public static AbstractType GetMethodReturnType(DMethod method, ResolverContextStack ctxt)
        {
            if (ctxt != null && ctxt.Options.HasFlag(ResolutionOptions.DontResolveBaseTypes))
            {
                return(null);
            }

            /*
             * If a method's type equals null, assume that it's an 'auto' function..
             * 1) Search for a return statement
             * 2) Resolve the returned expression
             * 3) Use that one as the method's type
             */
            bool pushMethodScope = ctxt.ScopedBlock != method;

            if (method.Type != null)
            {
                if (pushMethodScope)
                {
                    ctxt.PushNewScope(method);
                }

                //FIXME: Is it legal to explicitly return a nested type?
                var returnType = TypeDeclarationResolver.Resolve(method.Type, ctxt);

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

                if (ctxt.CheckForSingleResult(returnType, method.Type))
                {
                    return(returnType[0]);
                }
            }
            else if (method.Body != null)
            {
                ReturnStatement returnStmt = null;
                var             list       = new List <IStatement> {
                    method.Body
                };
                var list2 = new List <IStatement>();

                bool foundMatch = false;
                while (!foundMatch && list.Count > 0)
                {
                    foreach (var stmt in list)
                    {
                        if (stmt is ReturnStatement)
                        {
                            returnStmt = stmt as ReturnStatement;

                            if (!(returnStmt.ReturnExpression is TokenExpression) ||
                                (returnStmt.ReturnExpression as TokenExpression).Token != DTokens.Null)
                            {
                                foundMatch = true;
                                break;
                            }
                        }

                        if (stmt is StatementContainingStatement)
                        {
                            list2.AddRange((stmt as StatementContainingStatement).SubStatements);
                        }
                    }

                    list  = list2;
                    list2 = new List <IStatement>();
                }

                if (returnStmt != null && returnStmt.ReturnExpression != null)
                {
                    if (pushMethodScope)
                    {
                        var dedTypes = ctxt.CurrentContext.DeducedTemplateParameters;
                        ctxt.PushNewScope(method);
                        ctxt.CurrentContext.ScopedStatement = returnStmt;

                        if (dedTypes.Count != 0)
                        {
                            foreach (var kv in dedTypes)
                            {
                                ctxt.CurrentContext.DeducedTemplateParameters[kv.Key] = kv.Value;
                            }
                        }
                    }

                    var t = Evaluation.EvaluateType(returnStmt.ReturnExpression, ctxt);

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

                    return(t);
                }
            }

            return(null);
        }
コード例 #16
0
        public static AbstractType ResolveSingle(ITypeDeclaration declaration, ResolverContextStack ctxt)
        {
            if (declaration is IdentifierDeclaration)
                return ResolveSingle(declaration as IdentifierDeclaration, ctxt);
            else if (declaration is TemplateInstanceExpression)
            {
                var a = Evaluation.GetOverloads(declaration as TemplateInstanceExpression, ctxt);
                ctxt.CheckForSingleResult(a, declaration);
                return a != null && a.Length != 0 ? a[0] : null;
            }

            AbstractType t = null;

            if (declaration is DTokenDeclaration)
                t = Resolve(declaration as DTokenDeclaration);
            else if (declaration is TypeOfDeclaration)
                t = Resolve(declaration as TypeOfDeclaration, ctxt);
            else if (declaration is MemberFunctionAttributeDecl)
                t = Resolve(declaration as MemberFunctionAttributeDecl, ctxt);
            else if (declaration is ArrayDecl)
                t = Resolve(declaration as ArrayDecl, ctxt);
            else if (declaration is PointerDecl)
                t = Resolve(declaration as PointerDecl, ctxt);
            else if (declaration is DelegateDeclaration)
                t = Resolve(declaration as DelegateDeclaration, ctxt);

            //TODO: VarArgDeclaration
            else if (declaration is ITemplateParameterDeclaration)
            {
                var tpd = declaration as ITemplateParameterDeclaration;

                var templateParameter = tpd.TemplateParameter;

                //TODO: Is this correct handling?
                while (templateParameter is TemplateThisParameter)
                    templateParameter = (templateParameter as TemplateThisParameter).FollowParameter;

                if (tpd.TemplateParameter is TemplateValueParameter)
                {
                    // Return a member result -- it's a static variable
                }
                else
                {
                    // Return a type result?
                }
            }

            return t;
        }
コード例 #17
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);
        }
コード例 #18
0
        public static AbstractType Resolve(MemberFunctionAttributeDecl attrDecl, ResolverContextStack ctxt)
        {
            if (attrDecl != null)
            {
                var ret = Resolve(attrDecl.InnerType, ctxt);

                ctxt.CheckForSingleResult(ret, attrDecl.InnerType);

                if (ret != null && ret.Length != 0 && ret[0] != null)
                {
                    ret[0].Modifier = attrDecl.Modifier;
                    return ret[0];
                }
            }
            return null;
        }
コード例 #19
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;
        }
コード例 #20
0
        AbstractType HandleAccessExpressions(PostfixExpression_Access acc, ResolverContextStack ctxt)
        {
            AbstractType pfType = null;
            if (acc.PostfixForeExpression is PostfixExpression_Access)
                pfType = HandleAccessExpressions((PostfixExpression_Access)acc.PostfixForeExpression, ctxt);
            else
            {
                pfType = DResolver.StripAliasSymbol(Evaluation.EvaluateType(acc.PostfixForeExpression, ctxt));

                if (acc.PostfixForeExpression is IdentifierExpression ||
                    acc.PostfixForeExpression is TemplateInstanceExpression ||
                    acc.PostfixForeExpression is PostfixExpression_Access)
                    HandleResult(acc.PostfixForeExpression, pfType);
            }

            bool ufcs=false;
            var accessedMembers = Evaluation.GetAccessedOverloads(acc, ctxt, out ufcs, pfType);
            ctxt.CheckForSingleResult(accessedMembers, acc);

            if (accessedMembers != null && accessedMembers.Length != 0)
            {
                HandleResult(acc, accessedMembers[0]);
                return accessedMembers[0];
            }

            return null;
        }
コード例 #21
0
        public static AssocArrayType Resolve(ArrayDecl ad, ResolverContextStack ctxt)
        {
            var valueTypes = Resolve(ad.ValueType, ctxt);

            ctxt.CheckForSingleResult(valueTypes, ad);

            AbstractType valueType = null;
            AbstractType keyType=null;
            int fixedArrayLength = -1;

            if (valueTypes == null || valueTypes.Length == 0)
                return null;
            valueType = valueTypes[0];

            if (ad.KeyExpression != null)
            {
                var keyVal = Evaluation.EvaluateValue(ad.KeyExpression, ctxt);

                if (keyVal != null)
                {
                    // Take the value's type as array key type
                    keyType = keyVal.RepresentedType;

                    // It should be mostly a number only that points out how large the final array should be
                    var pv = Evaluation.GetVariableContents(keyVal, new StandardValueProvider(ctxt)) as PrimitiveValue;
                    if (pv != null)
                    {
                        fixedArrayLength = System.Convert.ToInt32(pv.Value);

                        if (fixedArrayLength < 0)
                            ctxt.LogError(ad, "Invalid array size: Length value must be greater than 0");
                    }
                    //TODO Is there any other type of value allowed?
                }
            }
            else
            {
                var t = Resolve(ad.KeyType, ctxt);
                ctxt.CheckForSingleResult(t, ad.KeyType);

                if (t != null && t.Length != 0)
                    keyType = t[0];
            }

            if (keyType== null || (keyType is PrimitiveType && ((PrimitiveType)keyType).TypeToken == DTokens.Int))
                return fixedArrayLength == -1 ?
                    new ArrayType(valueType, ad) :
                    new ArrayType(valueType, fixedArrayLength, ad);

            return new AssocArrayType(valueType, keyType, ad);
        }
コード例 #22
0
        public static PointerType Resolve(PointerDecl pd, ResolverContextStack ctxt)
        {
            var ptrBaseTypes = Resolve(pd.InnerDeclaration, ctxt);

            ctxt.CheckForSingleResult(ptrBaseTypes, pd);

            if (ptrBaseTypes == null || ptrBaseTypes.Length == 0)
                return null;

            return new PointerType(ptrBaseTypes[0], pd);
        }
コード例 #23
0
        public static DelegateType Resolve(DelegateDeclaration dg, ResolverContextStack ctxt)
        {
            var returnTypes = Resolve(dg.ReturnType, ctxt);

            ctxt.CheckForSingleResult(returnTypes, dg.ReturnType);

            if (returnTypes != null && returnTypes.Length != 0)
                return new DelegateType(returnTypes[0], dg); // Parameter types will be resolved later on
            return null;
        }
コード例 #24
0
        public static AbstractType ResolveSingle(string id, ResolverContextStack ctxt, object idObject, bool ModuleScope = false)
        {
            var r = ResolveIdentifier(id, ctxt, idObject, ModuleScope);

            ctxt.CheckForSingleResult(r, idObject as ISyntaxRegion);

            return r != null && r.Length != 0 ? r[0] : null;
        }
コード例 #25
0
        /// <summary>
        /// Takes the class passed via the tr, and resolves its base class and/or implemented interfaces.
        /// Also usable for enums.
        ///
        /// Never returns null. Instead, the original 'tr' object will be returned if no base class was resolved.
        /// Will clone 'tr', whereas the new object will contain the base class.
        /// </summary>
        public static UserDefinedType ResolveBaseClasses(UserDefinedType tr, ResolverContextStack ctxt, bool ResolveFirstBaseIdOnly = false)
        {
            if (bcStack > 8)
            {
                bcStack--;
                return(tr);
            }

            if (tr is EnumType)
            {
                var et = tr as EnumType;

                AbstractType bt = null;

                if (et.Definition.Type == null)
                {
                    bt = new PrimitiveType(DTokens.Int);
                }
                else
                {
                    if (tr.Definition.Parent is IBlockNode)
                    {
                        ctxt.PushNewScope((IBlockNode)tr.Definition.Parent);
                    }

                    var bts = TypeDeclarationResolver.Resolve(et.Definition.Type, ctxt);

                    if (tr.Definition.Parent is IBlockNode)
                    {
                        ctxt.Pop();
                    }

                    ctxt.CheckForSingleResult(bts, et.Definition.Type);

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

                return(new EnumType(et.Definition, bt, et.DeclarationOrExpressionBase));
            }

            var dc = tr.Definition as DClassLike;

            // Return immediately if searching base classes of the Object class
            if (dc == null || ((dc.BaseClasses == null || dc.BaseClasses.Count < 1) && dc.Name == "Object"))
            {
                return(tr);
            }

            // If no base class(es) specified, and if it's no interface that is handled, return the global Object reference
            // -- and do not throw any error message, it's ok
            if (dc.BaseClasses == null || dc.BaseClasses.Count < 1)
            {
                if (tr is ClassType)                // Only Classes can inherit from non-interfaces
                {
                    return(new ClassType(dc, tr.DeclarationOrExpressionBase, ctxt.ParseCache.ObjectClassResult));
                }
                return(tr);
            }

            #region Base class & interface resolution
            TemplateIntermediateType baseClass = null;
            var interfaces = new List <InterfaceType>();

            if (!(tr is ClassType || tr is InterfaceType))
            {
                if (dc.BaseClasses.Count != 0)
                {
                    ctxt.LogError(dc, "Only classes and interfaces may inherit from other classes/interfaces");
                }
                return(tr);
            }

            for (int i = 0; i < (ResolveFirstBaseIdOnly ? 1 : dc.BaseClasses.Count); i++)
            {
                var type = dc.BaseClasses[i];

                // If there's an explicit 'Object' inheritance, also return the pre-resolved object class
                if (type is IdentifierDeclaration && ((IdentifierDeclaration)type).Id == "Object")
                {
                    if (baseClass != null)
                    {
                        ctxt.LogError(new ResolutionError(dc, "Class must not have two base classes"));
                        continue;
                    }
                    else if (i != 0)
                    {
                        ctxt.LogError(new ResolutionError(dc, "The base class name must preceed base interfaces"));
                        continue;
                    }

                    baseClass = ctxt.ParseCache.ObjectClassResult;
                    continue;
                }

                if (type == null || type.ToString(false) == dc.Name || dc.NodeRoot == dc)
                {
                    ctxt.LogError(new ResolutionError(dc, "A class cannot inherit from itself"));
                    continue;
                }

                ctxt.PushNewScope(dc.Parent as IBlockNode);

                bcStack++;

                var res = TypeDeclarationResolver.Resolve(type, ctxt);

                ctxt.CheckForSingleResult(res, type);

                if (res != null && res.Length != 0)
                {
                    var r = res[0];
                    if (r is ClassType || r is TemplateType)
                    {
                        if (tr is InterfaceType)
                        {
                            ctxt.LogError(new ResolutionError(type, "An interface cannot inherit from non-interfaces"));
                        }
                        else if (i == 0)
                        {
                            baseClass = (TemplateIntermediateType)r;
                        }
                        else
                        {
                            ctxt.LogError(new ResolutionError(dc, "The base " + (r is ClassType ?  "class" : "template") + " name must preceed base interfaces"));
                        }
                    }
                    else if (r is InterfaceType)
                    {
                        interfaces.Add((InterfaceType)r);
                    }
                    else
                    {
                        ctxt.LogError(new ResolutionError(type, "Resolved class is neither a class nor an interface"));
                        continue;
                    }
                }

                bcStack--;

                ctxt.Pop();
            }
            #endregion

            if (baseClass == null && interfaces.Count == 0)
            {
                return(tr);
            }

            if (tr is ClassType)
            {
                return(new ClassType(dc, tr.DeclarationOrExpressionBase, baseClass, interfaces.Count == 0 ? null : interfaces.ToArray(), tr.DeducedTypes));
            }
            else if (tr is InterfaceType)
            {
                return(new InterfaceType(dc, tr.DeclarationOrExpressionBase, interfaces.Count == 0 ? null : interfaces.ToArray(), tr.DeducedTypes));
            }

            // Method should end here
            return(tr);
        }
コード例 #26
0
        public static AbstractType ResolveSingle(ITypeDeclaration declaration, ResolverContextStack ctxt)
        {
            if (declaration is IdentifierDeclaration)
            {
                return(ResolveSingle(declaration as IdentifierDeclaration, ctxt));
            }
            else if (declaration is TemplateInstanceExpression)
            {
                var a = Evaluation.GetOverloads(declaration as TemplateInstanceExpression, ctxt);
                ctxt.CheckForSingleResult(a, declaration);
                return(a != null && a.Length != 0 ? a[0] : null);
            }

            AbstractType t = null;

            if (declaration is DTokenDeclaration)
            {
                t = Resolve(declaration as DTokenDeclaration);
            }
            else if (declaration is TypeOfDeclaration)
            {
                t = Resolve(declaration as TypeOfDeclaration, ctxt);
            }
            else if (declaration is MemberFunctionAttributeDecl)
            {
                t = Resolve(declaration as MemberFunctionAttributeDecl, ctxt);
            }
            else if (declaration is ArrayDecl)
            {
                t = Resolve(declaration as ArrayDecl, ctxt);
            }
            else if (declaration is PointerDecl)
            {
                t = Resolve(declaration as PointerDecl, ctxt);
            }
            else if (declaration is DelegateDeclaration)
            {
                t = Resolve(declaration as DelegateDeclaration, ctxt);
            }

            //TODO: VarArgDeclaration
            else if (declaration is ITemplateParameterDeclaration)
            {
                var tpd = declaration as ITemplateParameterDeclaration;

                var templateParameter = tpd.TemplateParameter;

                //TODO: Is this correct handling?
                while (templateParameter is TemplateThisParameter)
                {
                    templateParameter = (templateParameter as TemplateThisParameter).FollowParameter;
                }

                if (tpd.TemplateParameter is TemplateValueParameter)
                {
                    // Return a member result -- it's a static variable
                }
                else
                {
                    // Return a type result?
                }
            }

            return(t);
        }
コード例 #27
0
        /// <summary>
        /// Tries to resolve a static property's name.
        /// Returns a result describing the theoretical member (".init"-%gt;MemberResult; ".typeof"-&gt;TypeResult etc).
        /// Returns null if nothing was found.
        /// </summary>
        /// <param name="InitialResult"></param>
        /// <returns></returns>
        public static MemberSymbol TryResolveStaticProperties(
            ISemantic InitialResult,
            string propertyIdentifier,
            ResolverContextStack ctxt          = null,
            bool Evaluate                      = false,
            IdentifierDeclaration idContainter = null)
        {
            // If a pointer'ed type is given, take its base type
            if (InitialResult is PointerType)
            {
                InitialResult = ((PointerType)InitialResult).Base;
            }

            if (InitialResult == null || InitialResult is ModuleSymbol)
            {
                return(null);
            }

            INode relatedNode = null;

            if (InitialResult is DSymbol)
            {
                relatedNode = ((DSymbol)InitialResult).Definition;
            }

            #region init
            if (propertyIdentifier == "init")
            {
                var prop_Init = new DVariable
                {
                    Name        = "init",
                    Description = "Initializer"
                };

                if (relatedNode != null)
                {
                    if (!(relatedNode is DVariable))
                    {
                        prop_Init.Parent = relatedNode.Parent;
                        prop_Init.Type   = new IdentifierDeclaration(relatedNode.Name);
                    }
                    else
                    {
                        prop_Init.Parent      = relatedNode;
                        prop_Init.Initializer = (relatedNode as DVariable).Initializer;
                        prop_Init.Type        = relatedNode.Type;
                    }
                }

                return(new MemberSymbol(prop_Init, DResolver.StripAliasSymbol(AbstractType.Get(InitialResult)), idContainter));
            }
            #endregion

            #region sizeof
            if (propertyIdentifier == "sizeof")
            {
                return(new MemberSymbol(new DVariable
                {
                    Name = "sizeof",
                    Type = new DTokenDeclaration(DTokens.Int),
                    Initializer = new IdentifierExpression(4),
                    Description = "Size in bytes (equivalent to C's sizeof(type))"
                }, new PrimitiveType(DTokens.Int), idContainter));
            }
            #endregion

            #region alignof
            if (propertyIdentifier == "alignof")
            {
                return(new MemberSymbol(new DVariable
                {
                    Name = "alignof",
                    Type = new DTokenDeclaration(DTokens.Int),
                    Description = "Alignment size"
                }, new PrimitiveType(DTokens.Int), idContainter));
            }
            #endregion

            #region mangleof
            if (propertyIdentifier == "mangleof")
            {
                return(new MemberSymbol(new DVariable
                {
                    Name = "mangleof",
                    Type = new IdentifierDeclaration("string"),
                    Description = "String representing the ‘mangled’ representation of the type"
                }, getStringType(ctxt), idContainter));
            }
            #endregion

            #region stringof
            if (propertyIdentifier == "stringof")
            {
                return(new MemberSymbol(new DVariable
                {
                    Name = "stringof",
                    Type = new IdentifierDeclaration("string"),
                    Description = "String representing the source representation of the type"
                }, getStringType(ctxt), idContainter));
            }
            #endregion

            #region classinfo
            else if (propertyIdentifier == "classinfo")
            {
                var tr = DResolver.StripMemberSymbols(AbstractType.Get(InitialResult)) as TemplateIntermediateType;

                if (tr is ClassType || tr is InterfaceType)
                {
                    var ci = new IdentifierDeclaration("TypeInfo_Class")
                    {
                        InnerDeclaration        = new IdentifierDeclaration("object"),
                        ExpressesVariableAccess = true,
                    };

                    var ti = TypeDeclarationResolver.Resolve(ci, ctxt);

                    ctxt.CheckForSingleResult(ti, ci);

                    return(new MemberSymbol(new DVariable {
                        Name = "classinfo", Type = ci
                    }, ti != null && ti.Length != 0?ti[0]:null, idContainter));
                }
            }
            #endregion

            //TODO: Resolve the types of type-specific properties (floats, ints, arrays, assocarrays etc.)

            return(null);
        }
コード例 #28
0
        public static AbstractType ResolveSingle(IdentifierDeclaration id, ResolverContextStack ctxt, AbstractType[] resultBases = null, bool filterForTemplateArgs = true)
        {
            var r = Resolve(id, ctxt, resultBases, filterForTemplateArgs);

            ctxt.CheckForSingleResult(r, id);

            return r != null && r.Length != 0 ? r[0] : null;
        }
コード例 #29
0
        public static AbstractType ResolveKey(ArrayDecl ad, out int fixedArrayLength, out ISymbolValue keyVal, ResolverContextStack ctxt)
        {
            keyVal           = null;
            fixedArrayLength = 0;
            AbstractType keyType = null;

            if (ad.KeyExpression != null)
            {
                //TODO: Template instance expressions?
                var id_x = ad.KeyExpression as IdentifierExpression;
                if (id_x != null && id_x.IsIdentifier)
                {
                    var id = new IdentifierDeclaration((string)id_x.Value)
                    {
                        Location    = id_x.Location,
                        EndLocation = id_x.EndLocation
                    };

                    keyType = TypeDeclarationResolver.ResolveSingle(id, ctxt);

                    if (keyType != null)
                    {
                        var tt = DResolver.StripAliasSymbol(keyType) as MemberSymbol;

                        if (tt == null ||
                            !(tt.Definition is DVariable) ||
                            ((DVariable)tt.Definition).Initializer == null)
                        {
                            return(keyType);
                        }
                    }
                }

                try
                {
                    keyVal = Evaluation.EvaluateValue(ad.KeyExpression, ctxt);

                    if (keyVal != null)
                    {
                        // Take the value's type as array key type
                        keyType = keyVal.RepresentedType;

                        // It should be mostly a number only that points out how large the final array should be
                        var pv = Evaluation.GetVariableContents(keyVal, new StandardValueProvider(ctxt)) as PrimitiveValue;
                        if (pv != null)
                        {
                            fixedArrayLength = System.Convert.ToInt32(pv.Value);

                            if (fixedArrayLength < 0)
                            {
                                ctxt.LogError(ad, "Invalid array size: Length value must be greater than 0");
                            }
                        }
                        //TODO Is there any other type of value allowed?
                    }
                }
                catch {}
            }
            else
            {
                var t = Resolve(ad.KeyType, ctxt);
                ctxt.CheckForSingleResult(t, ad.KeyType);

                if (t != null && t.Length != 0)
                {
                    return(t[0]);
                }
            }

            return(keyType);
        }
コード例 #30
0
        public static List<ISemantic> PreResolveTemplateArgs(TemplateInstanceExpression tix, ResolverContextStack ctxt)
        {
            // Resolve given argument expressions
            var templateArguments = new List<ISemantic>();

            if (tix != null && tix.Arguments!=null)
                foreach (var arg in tix.Arguments)
                {
                    if (arg is TypeDeclarationExpression)
                    {
                        var tde = (TypeDeclarationExpression)arg;

                        var res = TypeDeclarationResolver.Resolve(tde.Declaration, ctxt);

                        if (ctxt.CheckForSingleResult(res, tde.Declaration) || res != null)
                        {
                            var mr = res[0] as MemberSymbol;
                            if (mr != null && mr.Definition is DVariable)
                            {
                                var dv = (DVariable)mr.Definition;

                                if (dv.IsAlias || dv.Initializer == null)
                                {
                                    templateArguments.Add(mr);
                                    continue;
                                }

                                ISemantic eval = null;

                                try
                                {
                                    eval = new StandardValueProvider(ctxt)[dv];
                                }
                                catch(System.Exception ee) // Should be a non-const-expression error here only
                                {
                                    ctxt.LogError(dv.Initializer, ee.Message);
                                }

                                templateArguments.Add(eval==null ? (ISemantic)mr : eval);
                            }
                            else
                                templateArguments.Add(res[0]);
                        }
                    }
                    else
                        templateArguments.Add(Evaluation.EvaluateValue(arg, ctxt));
                }

            return templateArguments;
        }