public bool HandleDecl(TemplateTypeParameter p ,ITypeDeclaration td, ISemantic rr)
		{
			if (td is IdentifierDeclaration)
				return HandleDecl(p,(IdentifierDeclaration)td, rr);

			//HACK Ensure that no information gets lost by using this function 
			// -- getting a value but requiring an abstract type and just extract it from the value - is this correct behaviour?
			var at = DResolver.StripAliasSymbol(AbstractType.Get(rr));

			if (td is ArrayDecl)
				return HandleDecl(p,(ArrayDecl)td, DResolver.StripMemberSymbols(at) as AssocArrayType);
			else if (td is DTokenDeclaration)
				return HandleDecl((DTokenDeclaration)td, at);
			else if (td is DelegateDeclaration)
				return HandleDecl(p, (DelegateDeclaration)td, DResolver.StripMemberSymbols(at) as DelegateType);
			else if (td is PointerDecl)
				return HandleDecl(p, (PointerDecl)td, DResolver.StripMemberSymbols(at) as PointerType);
			else if (td is MemberFunctionAttributeDecl)
				return HandleDecl(p,(MemberFunctionAttributeDecl)td, at);
			else if (td is TypeOfDeclaration)
				return HandleDecl((TypeOfDeclaration)td, at);
			else if (td is VectorDeclaration)
				return HandleDecl((VectorDeclaration)td, at);
			else if (td is TemplateInstanceExpression)
				return HandleDecl(p,(TemplateInstanceExpression)td, at);

			return false;
		}
		bool HandleDecl(TemplateTypeParameter p, IdentifierDeclaration id, ISemantic r)
		{
			// Bottom-level reached
			if (id.InnerDeclaration == null && Contains(id.IdHash) && !id.ModuleScoped)
			{
				// Associate template param with r
				return Set((p != null && id.IdHash == p.NameHash) ? p : null, r, id.IdHash);
			}

			var deducee = DResolver.StripMemberSymbols(AbstractType.Get(r)) as DSymbol;
			if (id.InnerDeclaration != null && deducee != null && deducee.Definition.NameHash == id.IdHash)
			{
				var physicalParentType = TypeDeclarationResolver.HandleNodeMatch(deducee.Definition.Parent, ctxt, null, id.InnerDeclaration);
				if (HandleDecl(p, id.InnerDeclaration, physicalParentType))
				{
					if (Contains(id.IdHash))
						Set((p != null && id.IdHash == p.NameHash) ? p : null, deducee, id.IdHash);
					return true;
				}
			}

			/*
			 * If not stand-alone identifier or is not required as template param, resolve the id and compare it against r
			 */
			var _r = TypeDeclarationResolver.Resolve(id, ctxt);

			ctxt.CheckForSingleResult(_r, id);

			return _r != null && _r.Length != 0 && 
				(EnforceTypeEqualityWhenDeducing ?
				ResultComparer.IsEqual(r,_r[0]) :
				ResultComparer.IsImplicitlyConvertible(r,_r[0]));
		}
        bool HandleDecl(TemplateTypeParameter p, IdentifierDeclaration id, ISemantic r)
        {
            // Bottom-level reached
            if (id.InnerDeclaration == null && Contains(id.IdHash) && !id.ModuleScoped)
            {
                // Associate template param with r
                return(Set((p != null && id.IdHash == p.NameHash) ? p : null, r, id.IdHash));
            }

            var deducee = DResolver.StripMemberSymbols(AbstractType.Get(r)) as DSymbol;

            if (id.InnerDeclaration != null && deducee != null && deducee.Definition.NameHash == id.IdHash)
            {
                var physicalParentType = TypeDeclarationResolver.HandleNodeMatch(deducee.Definition.Parent, ctxt, null, id.InnerDeclaration);
                if (HandleDecl(p, id.InnerDeclaration, physicalParentType))
                {
                    if (Contains(id.IdHash))
                    {
                        Set((p != null && id.IdHash == p.NameHash) ? p : null, deducee, id.IdHash);
                    }
                    return(true);
                }
            }

            /*
             * If not stand-alone identifier or is not required as template param, resolve the id and compare it against r
             */
            var _r = TypeDeclarationResolver.ResolveSingle(id, ctxt);

            return(_r != null && (EnforceTypeEqualityWhenDeducing ?
                                  ResultComparer.IsEqual(r, _r) :
                                  ResultComparer.IsImplicitlyConvertible(r, _r)));
        }
        bool Handle(TemplateTypeParameter p, ISemantic arg)
        {
            // if no argument given, try to handle default arguments
            if (arg == null)
            {
                return(TryAssignDefaultType(p));
            }

            // If no spezialization given, assign argument immediately
            if (p.Specialization == null)
            {
                return(Set(p, arg, 0));
            }

            bool handleResult = HandleDecl(null, p.Specialization, arg);

            if (!handleResult)
            {
                return(false);
            }

            // Apply the entire argument to parameter p if there hasn't been no explicit association yet
            TemplateParameterSymbol tps;

            if (!TargetDictionary.TryGetValue(p, out tps) || tps == null)
            {
                TargetDictionary[p] = new TemplateParameterSymbol(p, arg);
            }

            return(true);
        }
        public bool HandleDecl(TemplateTypeParameter p, ITypeDeclaration td, ISemantic rr)
        {
            if (td is IdentifierDeclaration)
            {
                return(HandleDecl(p, (IdentifierDeclaration)td, rr));
            }

            if (TemplateInstanceHandler.IsNonFinalArgument(rr))
            {
                foreach (var tp in this.TargetDictionary.Keys.ToList())
                {
                    if (TargetDictionary[tp] == null)
                    {
                        TargetDictionary[tp] = new TemplateParameterSymbol(tp, null);
                    }
                }

                return(true);
            }

            //HACK Ensure that no information gets lost by using this function
            // -- getting a value but requiring an abstract type and just extract it from the value - is this correct behaviour?
            var at = AbstractType.Get(rr);

            if (td is ArrayDecl)
            {
                return(HandleDecl(p, (ArrayDecl)td, DResolver.StripMemberSymbols(at) as AssocArrayType));
            }
            else if (td is DTokenDeclaration)
            {
                return(HandleDecl((DTokenDeclaration)td, at));
            }
            else if (td is DelegateDeclaration)
            {
                return(HandleDecl(p, (DelegateDeclaration)td, DResolver.StripMemberSymbols(at) as DelegateType));
            }
            else if (td is PointerDecl)
            {
                return(HandleDecl(p, (PointerDecl)td, DResolver.StripMemberSymbols(at) as PointerType));
            }
            else if (td is MemberFunctionAttributeDecl)
            {
                return(HandleDecl(p, (MemberFunctionAttributeDecl)td, at));
            }
            else if (td is TypeOfDeclaration)
            {
                return(HandleDecl((TypeOfDeclaration)td, at));
            }
            else if (td is VectorDeclaration)
            {
                return(HandleDecl((VectorDeclaration)td, at));
            }
            else if (td is TemplateInstanceExpression)
            {
                return(HandleDecl(p, (TemplateInstanceExpression)td, at));
            }

            return(false);
        }
        public bool TryAssignDefaultType(TemplateTypeParameter p)
        {
            if (p == null || p.Default == null)
            {
                return(false);
            }

            using (ctxt.Push(DResolver.SearchBlockAt(ctxt.ScopedBlock.NodeRoot as IBlockNode, p.Default.Location), p.Default.Location))
            {
                var defaultTypeRes = TypeDeclarationResolver.ResolveSingle(p.Default, ctxt);
                return(defaultTypeRes != null && Set(p, defaultTypeRes, 0));
            }
        }
Пример #7
0
        /// <summary>
        /// Tests if t1 is more specialized than t2
        /// </summary>
        bool IsMoreSpecialized(TemplateTypeParameter t1, TemplateTypeParameter t2, Dictionary <TemplateParameter, ISemantic> t1_DummyParamList)
        {
            // If one parameter is not specialized it should be clear
            if (t1.Specialization != null && t2.Specialization == null)
            {
                return(true);
            }
            else if (t1.Specialization == null)             // Return false if t2 is more specialized or if t1 as well as t2 are not specialized
            {
                return(false);
            }

            return(IsMoreSpecialized(t1.Specialization, t2, t1_DummyParamList));
        }
		public bool TryAssignDefaultType(TemplateTypeParameter p)
		{
			if (p == null || p.Default == null)
				return false;

			IStatement stmt = null;
			ctxt.PushNewScope(DResolver.SearchBlockAt(ctxt.ScopedBlock.NodeRoot as IBlockNode, p.Default.Location, out stmt), stmt);

			var defaultTypeRes = TypeDeclarationResolver.Resolve(p.Default, ctxt);
			var b = defaultTypeRes != null && Set(p, defaultTypeRes.First(), 0);

			ctxt.Pop();

			return b;
		}
Пример #9
0
        bool HandleDecl(TemplateTypeParameter p, MemberFunctionAttributeDecl m, AbstractType r)
        {
            if (r == null || r.Modifier == 0)
            {
                return(false);
            }

            // Modifiers must be equal on both sides
            if (m.Modifier != r.Modifier)
            {
                return(false);
            }

            // Now compare the type inside the parentheses with the given type 'r'
            return(m.InnerType != null && HandleDecl(p, m.InnerType, r));
        }
Пример #10
0
        bool Handle(TemplateTypeParameter p, ISemantic arg)
        {
            // if no argument given, try to handle default arguments
            if (arg == null)
            {
                if (p.Default == null)
                {
                    return(false);
                }
                else
                {
                    IStatement stmt = null;
                    ctxt.PushNewScope(DResolver.SearchBlockAt(ctxt.ScopedBlock.NodeRoot as IBlockNode, p.Default.Location, out stmt));
                    ctxt.ScopedStatement = stmt;
                    var  defaultTypeRes = TypeDeclarationResolver.Resolve(p.Default, ctxt);
                    bool b = false;
                    if (defaultTypeRes != null)
                    {
                        b = Set(p, defaultTypeRes.First());
                    }
                    ctxt.Pop();
                    return(b);
                }
            }

            // If no spezialization given, assign argument immediately
            if (p.Specialization == null)
            {
                return(Set(p, arg));
            }

            bool handleResult = HandleDecl(p, p.Specialization, arg);

            if (!handleResult)
            {
                return(false);
            }

            // Apply the entire argument to parameter p if there hasn't been no explicit association yet
            if (!TargetDictionary.ContainsKey(p.Name) || TargetDictionary[p.Name] == null)
            {
                TargetDictionary[p.Name] = new TemplateParameterSymbol(p, arg);
            }

            return(true);
        }
Пример #11
0
        bool HandleDecl(TemplateTypeParameter p, ITypeDeclaration td, ISemantic rr)
        {
            if (td is IdentifierDeclaration)
            {
                return(HandleDecl(p, (IdentifierDeclaration)td, rr));
            }

            //HACK Ensure that no information gets lost by using this function
            // -- getting a value but requiring an abstract type and just extract it from the value - is this correct behaviour?
            var at = AbstractType.Get(rr);

            if (td is ArrayDecl)
            {
                return(HandleDecl(p, (ArrayDecl)td, at as AssocArrayType));
            }
            else if (td is DTokenDeclaration)
            {
                return(HandleDecl((DTokenDeclaration)td, at));
            }
            else if (td is DelegateDeclaration)
            {
                return(HandleDecl(p, (DelegateDeclaration)td, at as DelegateType));
            }
            else if (td is PointerDecl)
            {
                return(HandleDecl(p, (PointerDecl)td, at as PointerType));
            }
            else if (td is MemberFunctionAttributeDecl)
            {
                return(HandleDecl(p, (MemberFunctionAttributeDecl)td, at));
            }
            else if (td is TypeOfDeclaration)
            {
                return(HandleDecl((TypeOfDeclaration)td, at));
            }
            else if (td is VectorDeclaration)
            {
                return(HandleDecl((VectorDeclaration)td, at));
            }
            else if (td is TemplateInstanceExpression)
            {
                return(HandleDecl(p, (TemplateInstanceExpression)td, at));
            }

            return(false);
        }
        public bool TryAssignDefaultType(TemplateTypeParameter p)
        {
            if (p == null || p.Default == null)
            {
                return(false);
            }

            IStatement stmt = null;

            ctxt.PushNewScope(DResolver.SearchBlockAt(ctxt.ScopedBlock.NodeRoot as IBlockNode, p.Default.Location, out stmt), stmt);

            var defaultTypeRes = TypeDeclarationResolver.Resolve(p.Default, ctxt);
            var b = defaultTypeRes != null && Set(p, defaultTypeRes [0], 0);

            ctxt.Pop();

            return(b);
        }
        bool HandleDecl(TemplateTypeParameter p, MemberFunctionAttributeDecl m, AbstractType r)
        {
            if (r == null || r.Modifier == 0)
            {
                return(false);
            }

            // Modifiers must be equal on both sides
            if (m.Modifier != r.Modifier)
            {
                return(false);
            }

            // Strip modifier, but: immutable(int[]) becomes immutable(int)[] ?!
            AbstractType newR;

            if (r is AssocArrayType)
            {
                var aa = r as AssocArrayType;
                var clonedValueType = aa.Modifier != r.Modifier ? aa.ValueType.Clone(false) : aa.ValueType;
                clonedValueType.Modifier = r.Modifier;

                var at = aa as ArrayType;
                if (at != null)
                {
                    newR = at.IsStaticArray ? new ArrayType(clonedValueType, at.FixedLength, r.DeclarationOrExpressionBase) : new ArrayType(clonedValueType, r.DeclarationOrExpressionBase);
                }
                else
                {
                    newR = new AssocArrayType(clonedValueType, aa.KeyType, r.DeclarationOrExpressionBase);
                }
            }
            else
            {
                newR          = r.Clone(false);
                newR.Modifier = 0;
            }

            // Now compare the type inside the parentheses with the given type 'r'
            return(m.InnerType != null && HandleDecl(p, m.InnerType, newR));
        }
Пример #14
0
        bool HandleDecl(TemplateTypeParameter p, IdentifierDeclaration id, ISemantic r)
        {
            // Bottom-level reached
            if (id.InnerDeclaration == null && Contains(id.Id) && !id.ModuleScoped)
            {
                // Associate template param with r
                return(Set(p, r, id.Id));
            }

            /*
             * If not stand-alone identifier or is not required as template param, resolve the id and compare it against r
             */
            var _r = TypeDeclarationResolver.Resolve(id, ctxt);

            ctxt.CheckForSingleResult(_r, id);

            return(_r != null && _r.Length != 0 &&
                   (EnforceTypeEqualityWhenDeducing ?
                    ResultComparer.IsEqual(r, _r[0]) :
                    ResultComparer.IsImplicitlyConvertible(r, _r[0])));
        }
		bool Handle(TemplateTypeParameter p, ISemantic arg)
		{
			// if no argument given, try to handle default arguments
			if (arg == null)
				return TryAssignDefaultType(p);

			// If no spezialization given, assign argument immediately
			if (p.Specialization == null)
				return Set(p, arg, 0);

			bool handleResult= HandleDecl(null,p.Specialization,arg);

			if (!handleResult)
				return false;

			// Apply the entire argument to parameter p if there hasn't been no explicit association yet
			if (TargetDictionary[p.NameHash] == null)
				TargetDictionary[p.NameHash] = new TemplateParameterSymbol(p, arg);

			return true;
		}
Пример #16
0
		TemplateParameter TemplateParameter(DNode parent)
		{
			CodeLocation startLoc;

			// TemplateThisParameter
			if (laKind == (This))
			{
				Step();

				startLoc = t.Location;
				var end = t.EndLocation;

				var ret= new TemplateThisParameter(TemplateParameter(parent), parent) { Location=startLoc, EndLocation=end };
				LastParsedObject = ret;
				return ret;
			}

			// TemplateTupleParameter
			else if (laKind == (Identifier) && Lexer.CurrentPeekToken.Kind == TripleDot)
			{
				Step();
				startLoc = t.Location;
				var id = t.Value;
				Step();

				var ret=new TemplateTupleParameter(id, startLoc, parent) { Location=startLoc, EndLocation=t.EndLocation	};
				LastParsedObject = ret;
				return ret;
			}

			// TemplateAliasParameter
			else if (laKind == (Alias))
			{
				Step();

				startLoc = t.Location;
				TemplateAliasParameter al;

				if(Expect(Identifier))
					al = new TemplateAliasParameter(t.Value, t.Location, parent);
				else
					al = new TemplateAliasParameter(0, CodeLocation.Empty, parent);
				al.Location = startLoc;
				LastParsedObject = al;

				// TODO?:
				// alias BasicType Declarator TemplateAliasParameterSpecialization_opt TemplateAliasParameterDefault_opt

				// TemplateAliasParameterSpecialization
				if (laKind == (Colon))
				{
					Step();

					AllowWeakTypeParsing=true;
					al.SpecializationType = Type();
					AllowWeakTypeParsing=false;

					if (al.SpecializationType==null)
						al.SpecializationExpression = ConditionalExpression();
				}

				// TemplateAliasParameterDefault
				if (laKind == (Assign))
				{
					Step();

					AllowWeakTypeParsing=true;
					al.DefaultType = Type();
					AllowWeakTypeParsing=false;

					if (al.DefaultType==null)
						al.DefaultExpression = ConditionalExpression();
				}
				al.EndLocation = t.EndLocation;
				return al;
			}

			// TemplateTypeParameter
			else if (laKind == (Identifier) && (Lexer.CurrentPeekToken.Kind == (Colon) || Lexer.CurrentPeekToken.Kind == (Assign) || Lexer.CurrentPeekToken.Kind == (Comma) || Lexer.CurrentPeekToken.Kind == (CloseParenthesis)))
			{
				Expect(Identifier);
				var tt = new TemplateTypeParameter(t.Value, t.Location, parent) { Location = t.Location };
				LastParsedObject = tt;

				if (laKind == Colon)
				{
					Step();
					tt.Specialization = Type();
				}

				if (laKind == Assign)
				{
					Step();
					tt.Default = Type();
				}
				tt.EndLocation = t.EndLocation;
				return tt;
			}

			// TemplateValueParameter
			startLoc = la.Location;
			var bt = BasicType();
			var dv = Declarator(bt,false, null);

			if (dv == null) {
				SynErr (t.Kind, "Declarator expected for parsing template value parameter");
				return null;
			}

			var tv = new TemplateValueParameter(dv.NameHash, dv.NameLocation, parent) { 
				Location=la.Location,
				Type = dv.Type
			};
			LastParsedObject = tv;

			if (laKind == (Colon))
			{
				Step();
				tv.SpecializationExpression = ConditionalExpression();
			}

			if (laKind == (Assign))
			{
				Step();
				tv.DefaultExpression = AssignExpression();
			}
			tv.EndLocation = t.EndLocation;
			return tv;
		}
 bool HandleDecl(TemplateTypeParameter parameter, PointerDecl p, PointerType r)
 {
     return(r != null &&
            r.DeclarationOrExpressionBase is PointerDecl &&
            HandleDecl(parameter, p.InnerDeclaration, r.Base));
 }
		bool HandleDecl(TemplateTypeParameter parameterRef,ArrayDecl arrayDeclToCheckAgainst, AssocArrayType argumentArrayType)
		{
			if (argumentArrayType == null)
				return false;

			// Handle key type
			if((arrayDeclToCheckAgainst.KeyType != null || arrayDeclToCheckAgainst.KeyExpression!=null) && argumentArrayType.KeyType == null)
				return false;
			bool result = false;

			if (arrayDeclToCheckAgainst.KeyExpression != null)
			{
				// Remove all surrounding parentheses from the expression
				var x_param = arrayDeclToCheckAgainst.KeyExpression;

				while(x_param is SurroundingParenthesesExpression)
					x_param = ((SurroundingParenthesesExpression)x_param).Expression;

				var ad_Argument = argumentArrayType.DeclarationOrExpressionBase as ArrayDecl;

				/*
				 * This might be critical:
				 * the [n] part in class myClass(T:char[n], int n) {}
				 * will be seen as an identifier expression, not as an identifier declaration.
				 * So in the case the parameter expression is an identifier,
				 * test if it's part of the parameter list
				 */
				var id = x_param as IdentifierExpression;
				if(id!=null && id.IsIdentifier && Contains(id.ValueStringHash))
				{
					// If an expression (the usual case) has been passed as argument, evaluate its value, otherwise is its type already resolved.
					ISemantic finalArg = null;

					if (ad_Argument != null && ad_Argument.KeyExpression != null)
					{
						ISymbolValue val = null;
						int len = -1;
						finalArg = TypeDeclarationResolver.ResolveKey(ad_Argument, out len, out val, ctxt);
						if (val != null)
							finalArg = val;
					}
					else
						finalArg = argumentArrayType.KeyType;

					//TODO: Do a type convertability check between the param type and the given argument's type.
					// The affected parameter must also be a value parameter then, if an expression was given.

					// and handle it as if it was an identifier declaration..
					result = Set(parameterRef, finalArg, id.ValueStringHash); 
				}
				else if (ad_Argument != null && ad_Argument.KeyExpression != null)
				{
					// Just test for equality of the argument and parameter expression, e.g. if both param and arg are 123, the result will be true.
					result = SymbolValueComparer.IsEqual(arrayDeclToCheckAgainst.KeyExpression, ad_Argument.KeyExpression, new StandardValueProvider(ctxt));
				}
			}
			else if (arrayDeclToCheckAgainst.KeyType != null)
			{
				// If the array we're passing to the decl check that is static (i.e. has a constant number as key 'type'),
				// pass that number instead of type 'int' to the check.
				var at = argumentArrayType as ArrayType;
				if (argumentArrayType != null && at != null && at.IsStaticArray)
					result = HandleDecl(parameterRef, arrayDeclToCheckAgainst.KeyType,
						new PrimitiveValue(DSharp.Parser.DTokens.Int, (decimal)at.FixedLength, null)); 
				else
					result = HandleDecl(parameterRef, arrayDeclToCheckAgainst.KeyType, argumentArrayType.KeyType);
			}

			// Handle inner type
			return result && HandleDecl(parameterRef,arrayDeclToCheckAgainst.InnerDeclaration, argumentArrayType.Base);
		}
        bool HandleDecl(TemplateTypeParameter par, DelegateDeclaration d, DelegateType dr)
        {
            // Delegate literals or other expressions are not allowed
            if (dr == null || dr.IsFunctionLiteral)
            {
                return(false);
            }

            var dr_decl = (DelegateDeclaration)dr.DeclarationOrExpressionBase;

            // Compare return types
            if (d.IsFunction == dr_decl.IsFunction &&
                dr.ReturnType != null &&
                HandleDecl(par, d.ReturnType, dr.ReturnType))
            {
                // If no delegate args expected, it's valid
                if ((d.Parameters == null || d.Parameters.Count == 0) &&
                    dr_decl.Parameters == null || dr_decl.Parameters.Count == 0)
                {
                    return(true);
                }

                // If parameter counts unequal, return false
                else if (d.Parameters == null || dr_decl.Parameters == null || d.Parameters.Count != dr_decl.Parameters.Count)
                {
                    return(false);
                }

                // Compare & Evaluate each expected with given parameter
                var dr_paramEnum = dr_decl.Parameters.GetEnumerator();
                foreach (var p in d.Parameters)
                {
                    // Compare attributes with each other
                    if (p is DNode)
                    {
                        if (!(dr_paramEnum.Current is DNode))
                        {
                            return(false);
                        }

                        var dn     = (DNode)p;
                        var dn_arg = (DNode)dr_paramEnum.Current;

                        if ((dn.Attributes == null || dn.Attributes.Count == 0) &&
                            (dn_arg.Attributes == null || dn_arg.Attributes.Count == 0))
                        {
                            return(true);
                        }

                        else if (dn.Attributes == null || dn_arg.Attributes == null ||
                                 dn.Attributes.Count != dn_arg.Attributes.Count)
                        {
                            return(false);
                        }

                        foreach (var attr in dn.Attributes)
                        {
                            if (!dn_arg.ContainsAttribute(attr))
                            {
                                return(false);
                            }
                        }
                    }

                    // Compare types
                    if (p.Type != null && dr_paramEnum.MoveNext() && dr_paramEnum.Current.Type != null)
                    {
                        var dr_resolvedParamType = TypeDeclarationResolver.ResolveSingle(dr_paramEnum.Current.Type, ctxt);

                        if (dr_resolvedParamType == null ||
                            !HandleDecl(par, p.Type, dr_resolvedParamType))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
            }

            return(false);
        }
        bool HandleDecl(TemplateTypeParameter parameterRef, ArrayDecl arrayDeclToCheckAgainst, AssocArrayType argumentArrayType)
        {
            if (argumentArrayType == null)
            {
                return(false);
            }

            // Handle key type
            var at = argumentArrayType as ArrayType;

            if ((arrayDeclToCheckAgainst.ClampsEmpty == (at == null)) &&
                (at == null || !at.IsStaticArray || arrayDeclToCheckAgainst.KeyExpression == null))
            {
                return(false);
            }
            bool result;

            if (arrayDeclToCheckAgainst.KeyExpression != null)
            {
                // Remove all surrounding parentheses from the expression
                var x_param = arrayDeclToCheckAgainst.KeyExpression;

                while (x_param is SurroundingParenthesesExpression)
                {
                    x_param = ((SurroundingParenthesesExpression)x_param).Expression;
                }

                var ad_Argument = argumentArrayType.DeclarationOrExpressionBase as ArrayDecl;

                /*
                 * This might be critical:
                 * the [n] part in class myClass(T:char[n], int n) {}
                 * will be seen as an identifier expression, not as an identifier declaration.
                 * So in the case the parameter expression is an identifier,
                 * test if it's part of the parameter list
                 */
                var id = x_param as IdentifierExpression;
                if (id != null && id.IsIdentifier && Contains(id.ValueStringHash))
                {
                    // If an expression (the usual case) has been passed as argument, evaluate its value, otherwise is its type already resolved.
                    ISemantic finalArg = null;

                    if (ad_Argument != null && ad_Argument.KeyExpression != null)
                    {
                        ISymbolValue val = null;
                        int          len = -1;
                        finalArg = TypeDeclarationResolver.ResolveKey(ad_Argument, out len, out val, ctxt);
                        if (val != null)
                        {
                            finalArg = val;
                        }
                    }
                    else
                    {
                        finalArg = argumentArrayType.KeyType;
                    }

                    //TODO: Do a type convertability check between the param type and the given argument's type.
                    // The affected parameter must also be a value parameter then, if an expression was given.

                    // and handle it as if it was an identifier declaration..
                    result = Set(parameterRef, finalArg, id.ValueStringHash);
                }
                else if (ad_Argument != null && ad_Argument.KeyExpression != null)
                {
                    // Just test for equality of the argument and parameter expression, e.g. if both param and arg are 123, the result will be true.
                    result = SymbolValueComparer.IsEqual(arrayDeclToCheckAgainst.KeyExpression, ad_Argument.KeyExpression, new StandardValueProvider(ctxt));
                }
                else
                {
                    result = false;
                }

                if (!result)
                {
                    return(false);
                }
            }
            else if (arrayDeclToCheckAgainst.KeyType != null)
            {
                // If the array we're passing to the decl check that is static (i.e. has a constant number as key 'type'),
                // pass that number instead of type 'int' to the check.
                if (argumentArrayType != null && at != null && at.IsStaticArray)
                {
                    result = HandleDecl(parameterRef, arrayDeclToCheckAgainst.KeyType,
                                        new PrimitiveValue(D_Parser.Parser.DTokens.Int, (decimal)at.FixedLength, null));
                }
                else
                {
                    result = HandleDecl(parameterRef, arrayDeclToCheckAgainst.KeyType, argumentArrayType.KeyType);
                }

                if (!result)
                {
                    return(false);
                }
            }

            // Handle inner type
            return(HandleDecl(parameterRef, arrayDeclToCheckAgainst.InnerDeclaration, argumentArrayType.Base));
        }
        bool HandleDecl(TemplateTypeParameter parameter, TemplateInstanceExpression tix, AbstractType r)
        {
            /*
             * TODO: Scan down r for having at least one templateinstanceexpression as declaration base.
             * If a tix was found, check if the definition of the respective result base level
             * and the un-aliased identifier of the 'tix' parameter match.
             * Attention: if the alias represents an undeduced type (i.e. a type bundle of equally named type nodes),
             * it is only important that the definition is inside this bundle.
             * Therefore, it's needed to manually resolve the identifier, and look out for aliases or such unprecise aliases..confusing as s**t!
             *
             * If the param tix id is part of the template param list, the behaviour is currently undefined! - so instantly return false, I'll leave it as TODO/FIXME
             */
            var paramTix_TemplateMatchPossibilities       = ResolveTemplateInstanceId(tix);
            TemplateIntermediateType tixBasedArgumentType = null;
            var r_ = r as DSymbol;

            while (r_ != null)
            {
                if (r_.DeclarationOrExpressionBase is TemplateInstanceExpression)
                {
                    var tit = r_ as TemplateIntermediateType;
                    if (tit != null && CheckForTixIdentifierEquality(paramTix_TemplateMatchPossibilities, tit.Definition))
                    {
                        tixBasedArgumentType = tit;
                        break;
                    }
                }

                r_ = r_.Base as DSymbol;
            }

            /*
             * This part is very tricky:
             * I still dunno what is allowed over here--
             *
             * class Foo(T:Bar!E[],E) {}
             * ...
             * Foo!(Bar!string[]) f; -- E will be 'string' then
             *
             * class DerivateBar : Bar!string[] {} -- new Foo!DerivateBar() is also allowed, but now DerivateBar
             *		obviously is not a template instance expression - it's a normal identifier only.
             */
            if (tixBasedArgumentType != null)
            {
                var argEnum_given = ((TemplateInstanceExpression)tixBasedArgumentType.DeclarationOrExpressionBase).Arguments.GetEnumerator();

                foreach (var p in tix.Arguments)
                {
                    if (!argEnum_given.MoveNext() || argEnum_given.Current == null)
                    {
                        return(false);
                    }

                    // Convert p to type declaration
                    var param_Expected = ConvertToTypeDeclarationRoughly(p);

                    if (param_Expected == null)
                    {
                        return(false);
                    }

                    var result_Given = ExpressionTypeEvaluation.EvaluateType(argEnum_given.Current as IExpression, ctxt);

                    if (result_Given == null || !HandleDecl(parameter, param_Expected, result_Given))
                    {
                        return(false);
                    }
                }

                // Too many params passed..
                if (argEnum_given.MoveNext())
                {
                    return(false);
                }

                return(true);
            }

            return(false);
        }
		bool HandleDecl(TemplateTypeParameter par, DelegateDeclaration d, DelegateType dr)
		{
			// Delegate literals or other expressions are not allowed
			if(dr==null || dr.IsFunctionLiteral)
				return false;

			var dr_decl = (DelegateDeclaration)dr.DeclarationOrExpressionBase;

			// Compare return types
			if(	d.IsFunction == dr_decl.IsFunction &&
				dr.ReturnType != null &&
				HandleDecl(par, d.ReturnType,dr.ReturnType))
			{
				// If no delegate args expected, it's valid
				if ((d.Parameters == null || d.Parameters.Count == 0) &&
					dr_decl.Parameters == null || dr_decl.Parameters.Count == 0)
					return true;

				// If parameter counts unequal, return false
				else if (d.Parameters == null || dr_decl.Parameters == null || d.Parameters.Count != dr_decl.Parameters.Count)
					return false;

				// Compare & Evaluate each expected with given parameter
				var dr_paramEnum = dr_decl.Parameters.GetEnumerator();
				foreach (var p in d.Parameters)
				{
					// Compare attributes with each other
					if (p is DNode)
					{
						if (!(dr_paramEnum.Current is DNode))
							return false;

						var dn = (DNode)p;
						var dn_arg = (DNode)dr_paramEnum.Current;

						if ((dn.Attributes == null || dn.Attributes.Count == 0) &&
							(dn_arg.Attributes == null || dn_arg.Attributes.Count == 0))
							return true;

						else if (dn.Attributes == null || dn_arg.Attributes == null ||
							dn.Attributes.Count != dn_arg.Attributes.Count)
							return false;

						foreach (var attr in dn.Attributes)
						{
							if(!dn_arg.ContainsAttribute(attr))
								return false;
						}
					}

					// Compare types
					if (p.Type!=null && dr_paramEnum.MoveNext() && dr_paramEnum.Current.Type!=null)
					{
						var dr_resolvedParamType = TypeDeclarationResolver.Resolve(dr_paramEnum.Current.Type, ctxt);

						ctxt.CheckForSingleResult(dr_resolvedParamType, dr_paramEnum.Current.Type);

						if (dr_resolvedParamType == null ||
							dr_resolvedParamType.Length == 0 ||
							!HandleDecl(par, p.Type, dr_resolvedParamType[0]))
							return false;
					}
					else
						return false;
				}
			}

			return false;
		}
		bool HandleDecl(TemplateTypeParameter parameter, PointerDecl p, PointerType r)
		{
			return r != null && 
				r.DeclarationOrExpressionBase is PointerDecl && 
				HandleDecl(parameter, p.InnerDeclaration, r.Base);
		}
		bool HandleDecl(TemplateTypeParameter p, MemberFunctionAttributeDecl m, AbstractType r)
		{
			if (r == null || r.Modifier == 0)
				return false;

			// Modifiers must be equal on both sides
			if (m.Modifier != r.Modifier)
				return false;
				
			// Now compare the type inside the parentheses with the given type 'r'
			return m.InnerType != null && HandleDecl(p, m.InnerType, r);
		}
		/// <summary>
		/// Tests if t1 is more specialized than t2
		/// </summary>
		bool IsMoreSpecialized(TemplateTypeParameter t1, TemplateTypeParameter t2, Dictionary<int,ISemantic> t1_DummyParamList)
		{
			// If one parameter is not specialized it should be clear
			if (t1.Specialization != null && t2.Specialization == null)
				return true;
			else if (t1.Specialization == null) // Return false if t2 is more specialized or if t1 as well as t2 are not specialized
				return false;

			return IsMoreSpecialized(t1.Specialization, t2, t1_DummyParamList);
		}
Пример #26
0
        public AbstractType TryDeduce(DSymbol ds, IEnumerable <ISemantic> templateArguments, ref INode n)
        {
            TemplateTypeParameter tp;
            var t = ds as TemplateType;

            if (t == null)
            {
                return(null);
            }

            var orig        = ds.Definition;
            var tupleStruct = new DClassLike(DTokens.Struct)
            {
                NameHash     = ds.NameHash,
                Parent       = orig.Parent,
                Location     = orig.Location,
                EndLocation  = orig.EndLocation,
                NameLocation = orig.NameLocation
            };

            var ded = new Templates.DeducedTypeDictionary(tupleStruct);

            if (templateArguments != null)
            {
                var typeList = new List <AbstractType>();

                var en = templateArguments.GetEnumerator();
                if (en.MoveNext())
                {
                    var next = en.Current;
                    int i    = 0;
                    for (; ; i++)
                    {
                        var fieldType = AbstractType.Get(next);

                        if (fieldType == null)
                        {
                            break;
                        }

                        fieldType.NonStaticAccess = true;

                        typeList.Add(fieldType);

                        if (!en.MoveNext())
                        {
                            break;
                        }

                        next = en.Current;

                        if (next is ArrayValue && (next as ArrayValue).IsString)
                        {
                            var name = (next as ArrayValue).StringValue;
                            var templateParamName = "_" + i.ToString();
                            tp      = new TemplateTypeParameter(templateParamName, CodeLocation.Empty, tupleStruct);
                            ded[tp] = new TemplateParameterSymbol(tp, fieldType);

                            tupleStruct.Add(new DVariable {
                                Name = name, Type = new IdentifierDeclaration(templateParamName)
                            });

                            if (!en.MoveNext())
                            {
                                break;
                            }

                            next = en.Current;
                        }
                    }
                }

                var tupleName = "Types";
                tp      = new TemplateTypeParameter(tupleName, CodeLocation.Empty, tupleStruct);
                ded[tp] = new TemplateParameterSymbol(tp, new DTuple(null, typeList));

                tupleStruct.Add(new DVariable {
                    NameHash = DVariable.AliasThisIdentifierHash, IsAlias = true, IsAliasThis = true, Type = new IdentifierDeclaration(tupleName)
                });
            }

            n = tupleStruct;
            return(new StructType(tupleStruct, ds.DeclarationOrExpressionBase, ded.Count != 0 ? ded.Values : null));

            //TODO: Ensure renaming and other AST-based things run properly
        }
Пример #27
0
 public ulong Visit(TemplateTypeParameter templateTypeParameter)
 {
     return(1002101);
 }
Пример #28
0
        public AbstractType TryDeduce(DSymbol ds, IEnumerable <ISemantic> templateArguments, ref INode n)
        {
            TemplateTypeParameter tp;
            var t = ds as TemplateType;

            if (t == null)
            {
                return(null);
            }

            var orig        = ds.Definition;
            var tupleStruct = new DClassLike(DTokens.Struct)
            {
                NameHash     = ds.NameHash,
                Parent       = orig.Parent,
                Location     = orig.Location,
                EndLocation  = orig.EndLocation,
                NameLocation = orig.NameLocation
            };

            var ded = new Templates.DeducedTypeDictionary(tupleStruct);

            var sb = new StringBuilder();

            if (templateArguments != null)
            {
                var en = templateArguments.GetEnumerator();
                if (en.MoveNext())
                {
                    var next = en.Current;
                    int i    = 0;
                    for (; ; i++)
                    {
                        var fieldType = AbstractType.Get(next);

                        if (fieldType == null)
                        {
                            break;
                        }

                        fieldType.NonStaticAccess = true;

                        if (!en.MoveNext())
                        {
                            break;
                        }

                        next = en.Current;

                        if (next is ArrayValue && (next as ArrayValue).IsString)
                        {
                            var name = (next as ArrayValue).StringValue;
                            if (!string.IsNullOrWhiteSpace(name))
                            {
                                var templateParamName = "_" + i.ToString();
                                tp      = new TemplateTypeParameter(templateParamName, CodeLocation.Empty, tupleStruct);
                                ded[tp] = new TemplateParameterSymbol(tp, fieldType);

                                // getter
                                sb.Append("@property @safe ").Append(templateParamName).Append(' ').Append(name).AppendLine("() pure nothrow const {}");
                                // setter
                                sb.Append("@property @safe void ").Append(name).AppendLine("(").Append(templateParamName).AppendLine(" v) pure nothrow {}");
                                // constants
                                sb.Append("enum ").Append(templateParamName).Append(" ").Append(name).Append("_min = cast(").Append(templateParamName).AppendLine(") 0;");
                                sb.Append("enum ").Append(templateParamName).Append(" ").Append(name).Append("_max = cast(").Append(templateParamName).AppendLine(") 0;");
                            }
                            if (!en.MoveNext())
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }

                        if (!en.MoveNext())                         // Skip offset
                        {
                            break;
                        }

                        next = en.Current;
                    }
                }

                tupleStruct.Add(new DVariable {
                    NameHash   = tupleStruct.NameHash,
                    Attributes = new List <DAttribute> {
                        new Modifier(DTokens.Enum)
                    },
                    Initializer = new IdentifierExpression(sb.ToString(), LiteralFormat.StringLiteral, LiteralSubformat.Utf8)
                });
            }

            n = tupleStruct;
            return(new TemplateType(tupleStruct, ds.DeclarationOrExpressionBase, ded.Count != 0 ? ded.Values : null));
        }
		public virtual void Visit(TemplateTypeParameter p)
		{
			VisitTemplateParameter (p);

			if (p.Specialization != null)
				p.Specialization.Accept(this);

			if (p.Default != null)
				p.Default.Accept(this);
		}
		bool HandleDecl(TemplateTypeParameter parameter, TemplateInstanceExpression tix, AbstractType r)
		{
			/*
			 * TODO: Scan down r for having at least one templateinstanceexpression as declaration base.
			 * If a tix was found, check if the definition of the respective result base level 
			 * and the un-aliased identifier of the 'tix' parameter match.
			 * Attention: if the alias represents an undeduced type (i.e. a type bundle of equally named type nodes),
			 * it is only important that the definition is inside this bundle.
			 * Therefore, it's needed to manually resolve the identifier, and look out for aliases or such unprecise aliases..confusing as s**t!
			 * 
			 * If the param tix id is part of the template param list, the behaviour is currently undefined! - so instantly return false, I'll leave it as TODO/FIXME
			 */
			var paramTix_TemplateMatchPossibilities = ResolveTemplateInstanceId(tix);
			TemplateIntermediateType tixBasedArgumentType = null;
			var r_ = r as DSymbol;
			while (r_ != null)
			{
				if (r_.DeclarationOrExpressionBase is TemplateInstanceExpression)
				{
					var tit = r_ as TemplateIntermediateType;
					if (tit != null && CheckForTixIdentifierEquality(paramTix_TemplateMatchPossibilities, tit.Definition))
					{
						tixBasedArgumentType = tit;
						break;
					}
				}

				r_ = r_.Base as DSymbol;
			}

			/*
			 * This part is very tricky:
			 * I still dunno what is allowed over here--
			 * 
			 * class Foo(T:Bar!E[],E) {}
			 * ...
			 * Foo!(Bar!string[]) f; -- E will be 'string' then
			 * 
			 * class DerivateBar : Bar!string[] {} -- new Foo!DerivateBar() is also allowed, but now DerivateBar
			 *		obviously is not a template instance expression - it's a normal identifier only. 
			 */
			if (tixBasedArgumentType != null)
			{
				var argEnum_given = ((TemplateInstanceExpression)tixBasedArgumentType.DeclarationOrExpressionBase).Arguments.GetEnumerator();

				foreach (var p in tix.Arguments)
				{
					if (!argEnum_given.MoveNext() || argEnum_given.Current == null)
						return false;

					// Convert p to type declaration
					var param_Expected = ConvertToTypeDeclarationRoughly(p);

					if (param_Expected == null)
						return false;

					var result_Given = Evaluation.EvaluateType(argEnum_given.Current as IExpression, ctxt);

					if (result_Given == null || !HandleDecl(parameter, param_Expected, result_Given))
						return false;
				}

				// Too many params passed..
				if (argEnum_given.MoveNext())
					return false;

				return true;
			}

			return false;
		}