Exemple #1
0
        public AbstractType TryDeduce(DSymbol ds, IEnumerable <ISemantic> templateArguments, ref INode returnedNode)
        {
            var cls = ds as ClassType;

            if (cls == null || templateArguments == null)
            {
                return(null);
            }

            var en = templateArguments.GetEnumerator();

            if (!en.MoveNext())
            {
                return(null);
            }

            returnedNode = cls.Definition;
            var baseClass = DResolver.StripMemberSymbols(AbstractType.Get(en.Current)) as TemplateIntermediateType;

            if (baseClass == null)
            {
                return(ds);
            }

            return(new ClassType(cls.Definition, ds.DeclarationOrExpressionBase, baseClass as ClassType, baseClass is InterfaceType ? new[] { baseClass as InterfaceType } : null, ds.DeducedTypes));
        }
Exemple #2
0
        private static bool DeduceParams(IEnumerable <ISemantic> givenTemplateArguments,
                                         bool isMethodCall,
                                         ResolutionContext ctxt,
                                         DSymbol overload,
                                         DNode tplNode,
                                         DeducedTypeDictionary deducedTypes)
        {
            bool isLegitOverload = true;

            var paramEnum = tplNode.TemplateParameters.GetEnumerator();

            var args = givenTemplateArguments ?? new List <ISemantic> ();

            var argEnum = args.GetEnumerator();

            foreach (var expectedParam in tplNode.TemplateParameters)
            {
                if (!DeduceParam(ctxt, overload, deducedTypes, argEnum, expectedParam))
                {
                    isLegitOverload = false;
                    break;                     // Don't check further params if mismatch has been found
                }
            }

            if (!isMethodCall && argEnum.MoveNext())
            {
                // There are too many arguments passed - discard this overload
                isLegitOverload = false;
            }
            return(isLegitOverload);
        }
Exemple #3
0
        public DeducedTypeDictionary(DSymbol ms)
        {
            ExpectedParameters = ms.Definition.TemplateParameters;

            if (ms.DeducedTypes != null)
            {
                foreach (var i in ms.DeducedTypes)
                {
                    this.Add(i.NameHash, i);
                }
            }
        }
Exemple #4
0
 public DeducedTypeDictionary(DSymbol ms) : this(ms.ValidSymbol ? ms.Definition.TemplateParameters : null)
 {
     if (ms.DeducedTypes != null)
     {
         foreach (var i in ms.DeducedTypes)
         {
             if (i != null)
             {
                 this [i.Parameter] = i;
             }
         }
     }
 }
Exemple #5
0
        public static AbstractType TryDeduce(DSymbol t, IEnumerable<ISemantic> templateArguments, out bool supersedeOtherOverloads)
        {
            var def = t.Definition;
            IHook hook;
            if (def != null && DeductionHooks.TryGetValue(AbstractNode.GetNodePath(def, true), out hook))
            {
                supersedeOtherOverloads = hook.SupersedesMultipleOverloads;
                return hook.TryDeduce(t, templateArguments);
            }

            supersedeOtherOverloads = true;
            return null;
        }
		public AbstractType TryDeduce (DSymbol ds, IEnumerable<ISemantic> templateArguments, ref INode returnedNode)
		{
			var cls= ds as ClassType;
			if (cls == null || templateArguments == null)
				return null;

			var en = templateArguments.GetEnumerator ();
			if (!en.MoveNext ())
				return null;

			returnedNode = cls.Definition;
			var baseClass = DResolver.StripMemberSymbols(AbstractType.Get(en.Current)) as TemplateIntermediateType;

			if (baseClass == null)
				return ds;

			return new ClassType(cls.Definition, baseClass as ClassType, baseClass is InterfaceType ? new[] {baseClass as InterfaceType} : null, ds.DeducedTypes);
		}
Exemple #7
0
        public static AbstractType TryDeduce(DSymbol t, IEnumerable <ISemantic> templateArguments, out bool supersedeOtherOverloads)
        {
            var   def = t.Definition;
            IHook hook;

            if (def != null && DeductionHooks.TryGetValue(AbstractNode.GetNodePath(def, true), out hook))
            {
                supersedeOtherOverloads = hook.SupersedesMultipleOverloads;
                INode n   = null;
                var   res = hook.TryDeduce(t, templateArguments, ref n);
                if (n != null)
                {
                    resultStore.Add(res, n);
                }
                return(res);
            }

            supersedeOtherOverloads = true;
            return(null);
        }
Exemple #8
0
        private static bool DeduceParam(ResolutionContext ctxt,
                                        DSymbol overload,
                                        DeducedTypeDictionary deducedTypes,
                                        IEnumerator <ISemantic> argEnum,
                                        TemplateParameter expectedParam)
        {
            if (expectedParam is TemplateThisParameter && overload.Base != null)
            {
                var ttp = (TemplateThisParameter)expectedParam;

                // Get the type of the type of 'this' - so of the result that is the overload's base
                var t = DResolver.StripMemberSymbols(overload.Base);

                if (t == null || t.DeclarationOrExpressionBase == null)
                {
                    return(false);
                }

                //TODO: Still not sure if it's ok to pass a type result to it
                // - looking at things like typeof(T) that shall return e.g. const(A) instead of A only.

                if (!CheckAndDeduceTypeAgainstTplParameter(ttp, t, deducedTypes, ctxt))
                {
                    return(false);
                }

                return(true);
            }

            // Used when no argument but default arg given
            bool useDefaultType = false;

            if (argEnum.MoveNext() || (useDefaultType = HasDefaultType(expectedParam)))
            {
                // On tuples, take all following arguments and pass them to the check function
                if (expectedParam is TemplateTupleParameter)
                {
                    var tupleItems = new List <ISemantic>();
                    // A tuple must at least contain one item!
                    tupleItems.Add(argEnum.Current);
                    while (argEnum.MoveNext())
                    {
                        tupleItems.Add(argEnum.Current);
                    }

                    if (!CheckAndDeduceTypeTuple((TemplateTupleParameter)expectedParam, tupleItems, deducedTypes, ctxt))
                    {
                        return(false);
                    }
                }
                else if (argEnum.Current != null)
                {
                    if (!CheckAndDeduceTypeAgainstTplParameter(expectedParam, argEnum.Current, deducedTypes, ctxt))
                    {
                        return(false);
                    }
                }
                else if (useDefaultType && CheckAndDeduceTypeAgainstTplParameter(expectedParam, null, deducedTypes, ctxt))
                {
                    // It's legit - just do nothing
                }
                else
                {
                    return(false);
                }
            }
            else if (expectedParam is TemplateTupleParameter)
            {
                if (!CheckAndDeduceTypeTuple(expectedParam as TemplateTupleParameter, null, deducedTypes, ctxt))
                {
                    return(false);
                }
            }
            // There might be too few args - but that doesn't mean that it's not correct - it's only required that all parameters got satisfied with a type
            else if (!deducedTypes.AllParamatersSatisfied)
            {
                return(false);
            }

            return(true);
        }
Exemple #9
0
 public static ISymbolValue TryEvaluate(DSymbol t, IEnumerable<ISemantic> templateArgs)
 {
     return null;
 }
Exemple #10
0
        public static DNode ExamTraceSymbol(string symName, ResolutionContext ctxt, out bool mightBeLegalUnresolvableSymbol)
        {
            DSymbol ds = null;

            mightBeLegalUnresolvableSymbol = false;

            if (string.IsNullOrWhiteSpace(symName))
            {
                return(null);
            }

            // Try to handle a probably mangled string or C function.
            if (symName.StartsWith("_"))
            {
                try{
                    ds = Demangler.DemangleAndResolve(symName, ctxt) as DSymbol;
                }catch {}
            }

            // Stuff like void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[])
            if (ds == null && Lexer.IsIdentifierPart((int)symName[0]))
            {
                mightBeLegalUnresolvableSymbol = true;
                ITypeDeclaration q;
                var method = DParser.ParseMethodDeclarationHeader(symName, out q);
                q           = Demangler.RemoveNestedTemplateRefsFromQualifier(q);
                method.Type = Demangler.RemoveNestedTemplateRefsFromQualifier(method.Type);
                var methodType       = TypeDeclarationResolver.GetMethodReturnType(method, ctxt);
                var methodParameters = new List <AbstractType>();

                if (method.Parameters != null && method.Parameters.Count != 0)
                {
                    foreach (var parm in method.Parameters)
                    {
                        methodParameters.Add(TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(parm.Type), ctxt));
                    }
                }

                ctxt.ContextIndependentOptions |= ResolutionOptions.IgnoreAllProtectionAttributes;
                var overloads = TypeDeclarationResolver.Resolve(q, ctxt);


                if (overloads == null || overloads.Length == 0)
                {
                    return(null);
                }
                else if (overloads.Length == 1)
                {
                    ds = overloads[0] as DSymbol;
                }
                else
                {
                    foreach (var o in overloads)
                    {
                        ds = o as DSymbol;
                        if (ds == null || !(ds.Definition is DMethod))
                        {
                            continue;
                        }

                        var dm = ds.Definition as DMethod;
                        // Compare return types
                        if (dm.Type != null)
                        {
                            if (methodType == null || ds.Base == null || !ResultComparer.IsEqual(methodType, ds.Base))
                            {
                                continue;
                            }
                        }
                        else if (dm.Type == null && methodType != null)
                        {
                            return(null);
                        }

                        // Compare parameters
                        if (methodParameters.Count != dm.Parameters.Count)
                        {
                            continue;
                        }

                        for (int i = 0; i < methodParameters.Count; i++)
                        {
                            if (!ResultComparer.IsImplicitlyConvertible(methodParameters[i], TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(dm.Parameters[i].Type), ctxt)))
                            {
                                continue;
                            }
                        }
                    }
                }
            }

            if (ds != null)
            {
                return(ds.Definition);
            }
            return(null);
        }
Exemple #11
0
        /// <summary>
        /// Scans a block node. Not working with DMethods.
        /// Automatically resolves node matches so base types etc. will be specified directly after the search operation.
        /// </summary>
        public static List <AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, DSymbol t, int nameHash, ISyntaxRegion idObject = null)
        {
            var scan = new SingleNodeNameScan(ctxt, nameHash, idObject);

            if (t is TemplateIntermediateType)
            {
                scan.DeepScanClass(t as UserDefinedType, MemberFilter.All);
            }
            else if (t.Definition is IBlockNode)
            {
                scan.ScanBlock(t.Definition as IBlockNode, CodeLocation.Empty, MemberFilter.All);
            }

            return(scan.matches_types);
        }
        private static bool DeduceParam(ResolutionContext ctxt, 
			DSymbol overload, 
			DeducedTypeDictionary deducedTypes,
			IEnumerator<ISemantic> argEnum, 
			TemplateParameter expectedParam)
        {
            if (expectedParam is TemplateThisParameter && overload.Base != null)
            {
                var ttp = (TemplateThisParameter)expectedParam;

                // Get the type of the type of 'this' - so of the result that is the overload's base
                var t = DResolver.StripMemberSymbols(overload.Base);

                if (t == null || t.DeclarationOrExpressionBase == null)
                    return false;

                //TODO: Still not sure if it's ok to pass a type result to it
                // - looking at things like typeof(T) that shall return e.g. const(A) instead of A only.

                if (!CheckAndDeduceTypeAgainstTplParameter(ttp, t, deducedTypes, ctxt))
                    return false;

                return true;
            }

            // Used when no argument but default arg given
            bool useDefaultType = false;
            if (argEnum.MoveNext() || (useDefaultType = HasDefaultType(expectedParam)))
            {
                // On tuples, take all following arguments and pass them to the check function
                if (expectedParam is TemplateTupleParameter)
                {
                    var tupleItems = new List<ISemantic>();
                    // A tuple must at least contain one item!
                    tupleItems.Add(argEnum.Current);
                    while (argEnum.MoveNext())
                        tupleItems.Add(argEnum.Current);

                    if (!CheckAndDeduceTypeTuple((TemplateTupleParameter)expectedParam, tupleItems, deducedTypes, ctxt))
                        return false;
                }
                else if (argEnum.Current != null)
                {
                    if (!CheckAndDeduceTypeAgainstTplParameter(expectedParam, argEnum.Current, deducedTypes, ctxt))
                        return false;
                }
                else if (useDefaultType && CheckAndDeduceTypeAgainstTplParameter(expectedParam, null, deducedTypes, ctxt))
                {
                    // It's legit - just do nothing
                }
                else
                    return false;
            }
            else if(expectedParam is TemplateTupleParameter)
            {
                if(!CheckAndDeduceTypeTuple(expectedParam as TemplateTupleParameter, null, deducedTypes, ctxt))
                    return false;
            }
            // There might be too few args - but that doesn't mean that it's not correct - it's only required that all parameters got satisfied with a type
            else if (!deducedTypes.AllParamatersSatisfied)
                return false;

            return true;
        }
Exemple #13
0
        /// <summary>
        /// Scans a block node. Not working with DMethods.
        /// Automatically resolves node matches so base types etc. will be specified directly after the search operation.
        /// </summary>
        public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, DSymbol t, int nameHash, ISyntaxRegion idObject = null)
        {
            var scan = new SingleNodeNameScan(ctxt, nameHash, idObject);

            if (t is TemplateIntermediateType)
                scan.DeepScanClass(t as UserDefinedType, MemberFilter.All);
            else if (t.Definition is IBlockNode)
                scan.ScanBlock(t.Definition as IBlockNode, CodeLocation.Empty, MemberFilter.All);

            return scan.matches_types;
        }
Exemple #14
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
        }
Exemple #15
0
        public static DNode ExamTraceSymbol(string symName, ResolutionContext ctxt, out bool mightBeLegalUnresolvableSymbol)
        {
            DSymbol ds = null;

            mightBeLegalUnresolvableSymbol = false;

            if (string.IsNullOrWhiteSpace(symName))
            {
                return(null);
            }

            // Try to handle a probably mangled string or C function.
            if (symName.StartsWith("_"))
            {
                try{
                    ds = Demangler.DemangleAndResolve(symName, ctxt) as DSymbol;
                }catch {}
            }

            // Stuff like void std.stdio.File.LockingTextWriter.put!(immutable(char)[]).put(immutable(char)[])
            if (ds == null && Lexer.IsIdentifierPart((int)symName[0]))
            {
                mightBeLegalUnresolvableSymbol = true;
                ITypeDeclaration q;
                var method = DParser.ParseMethodDeclarationHeader(symName, out q);
                q = Demangler.RemoveNestedTemplateRefsFromQualifier(q);

                AbstractType[] overloads = null;
                D_Parser.Completion.CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () => {
                    try {
                        overloads = AmbiguousType.TryDissolve(LooseResolution.LookupIdRawly(ctxt.ParseCache, q, ctxt.ScopedBlock.NodeRoot as DModule)).ToArray();
                    }
                    catch (Exception ex) { MonoDevelop.Core.LoggingService.LogWarning("Error during trace.log symbol resolution of " + q.ToString(), ex); }
                });

                if (overloads == null || overloads.Length == 0)
                {
                    return(null);
                }
                else if (overloads.Length == 1)
                {
                    ds = overloads[0] as DSymbol;
                }
                else
                {
                    method.Type = Demangler.RemoveNestedTemplateRefsFromQualifier(method.Type);
                    var methodType = TypeDeclarationResolver.GetMethodReturnType(method, ctxt);

                    var methodParameters = new List <AbstractType>();
                    D_Parser.Completion.CodeCompletion.DoTimeoutableCompletionTask(null, ctxt, () => {
                        if (method.Parameters != null && method.Parameters.Count != 0)
                        {
                            foreach (var parm in method.Parameters)
                            {
                                methodParameters.Add(TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(parm.Type), ctxt));
                            }
                        }
                    });

                    foreach (var o in overloads)
                    {
                        ds = o as DSymbol;
                        if (ds == null || !(ds.Definition is DMethod))
                        {
                            continue;
                        }

                        var dm = ds.Definition as DMethod;
                        // Compare return types
                        if (dm.Type != null)
                        {
                            if (methodType == null || ds.Base == null || !ResultComparer.IsEqual(methodType, ds.Base))
                            {
                                continue;
                            }
                        }
                        else if (dm.Type == null && methodType != null)
                        {
                            return(null);
                        }

                        // Compare parameters
                        if (methodParameters.Count != dm.Parameters.Count)
                        {
                            continue;
                        }

                        for (int i = 0; i < methodParameters.Count; i++)
                        {
                            if (!ResultComparer.IsImplicitlyConvertible(methodParameters[i], TypeDeclarationResolver.ResolveSingle(Demangler.RemoveNestedTemplateRefsFromQualifier(dm.Parameters[i].Type), ctxt)))
                            {
                                continue;
                            }
                        }
                    }
                }
            }

            return(ds != null ? ds.Definition : null);
        }
Exemple #16
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, ded.Count != 0 ? ded.Values : null);
		}
Exemple #17
0
        protected void Handle(ISyntaxRegion o, DSymbol resolvedSymbol)
        {
            if (o is IdentifierDeclaration)
            {
                var id = (IdentifierDeclaration)o;

                if (id.Id != searchId)
                {
                    return;
                }

                if (resolvedSymbol == null)
                {
                    resolvedSymbol = TypeDeclarationResolver.ResolveSingle(id, ctxt) as DSymbol;
                }
            }
            else if (o is TemplateInstanceExpression)
            {
                var tix = (TemplateInstanceExpression)o;

                if (tix.TemplateIdentifier.Id != searchId)
                {
                    return;
                }

                if (resolvedSymbol == null)
                {
                    resolvedSymbol = Evaluation.EvaluateType(tix, ctxt) as DSymbol;
                }
            }
            else if (o is IdentifierExpression)
            {
                var id = (IdentifierExpression)o;

                if ((string)id.Value != searchId)
                {
                    return;
                }

                if (resolvedSymbol == null)
                {
                    resolvedSymbol = Evaluation.EvaluateType(id, ctxt) as DSymbol;
                }
            }
            else if (o is PostfixExpression_Access)
            {
                var acc = (PostfixExpression_Access)o;

                if ((acc.AccessExpression is IdentifierExpression &&
                     (string)((IdentifierExpression)acc.AccessExpression).Value != searchId) ||
                    (acc.AccessExpression is TemplateInstanceExpression &&
                     (string)((TemplateInstanceExpression)acc.AccessExpression).TemplateIdentifier.Id != searchId))
                {
                    Handle(acc.PostfixForeExpression, null);
                    return;
                }
                else if (acc.AccessExpression is NewExpression)
                {
                    var nex = (NewExpression)acc.AccessExpression;

                    if ((nex.Type is IdentifierDeclaration &&
                         ((IdentifierDeclaration)nex.Type).Id != searchId) ||
                        (nex.Type is TemplateInstanceExpression &&
                         (string)((TemplateInstanceExpression)acc.AccessExpression).TemplateIdentifier.Id != searchId))
                    {
                        Handle(acc.PostfixForeExpression, null);
                        return;
                    }
                    // Are there other types to test for?
                }

                var s = resolvedSymbol ?? Evaluation.EvaluateType(acc, ctxt) as DerivedDataType;

                if (s is DSymbol)
                {
                    if (((DSymbol)s).Definition == symbol)
                    {
                        l.Add(acc.AccessExpression);
                    }
                }
                else if (s == null || !(s.Base is DSymbol))
                {
                    return;
                }

                // Scan down for other possible symbols
                Handle(acc.PostfixForeExpression, s.Base as DSymbol);
                return;
            }

            // The resolved node must be equal to the symbol definition that is looked for.
            if (resolvedSymbol == null ||
                resolvedSymbol.Definition != symbol)
            {
                return;
            }

            l.Add(o);
        }
Exemple #18
0
        /*
        public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, IBlockNode block, string name, ISyntaxRegion idObject = null)
        {
            return SearchChildrenAndResolve (ctxt, block, name.GetHashCode(), idObject);
        }

        /// <summary>
        /// Scans a block node. Not working with DMethods.
        /// Automatically resolves node matches so base types etc. will be specified directly after the search operation.
        /// </summary>
        public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, IBlockNode block, int nameHash, ISyntaxRegion idObject = null)
        {
            var scan = new SingleNodeNameScan(ctxt, nameHash, idObject);

            scan.ScanBlock(block, CodeLocation.Empty, MemberFilter.All);

            return scan.matches_types;
        }*/
        public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, DSymbol t, string name, ISyntaxRegion idObject = null)
        {
            return SearchChildrenAndResolve(ctxt, t, name.GetHashCode(), idObject);
        }
Exemple #19
0
        public AbstractType TryDeduce(DSymbol ds, IEnumerable<ISemantic> templateArguments)
        {
            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) });
            }

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

            resultStore.Add(res, tupleStruct);

            //TODO: Ensure renaming and other AST-based things run properly

            return res;
        }
Exemple #20
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));
        }
Exemple #21
0
        /*
         * public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, IBlockNode block, string name, ISyntaxRegion idObject = null)
         * {
         *      return SearchChildrenAndResolve (ctxt, block, name.GetHashCode(), idObject);
         * }
         *
         * /// <summary>
         * /// Scans a block node. Not working with DMethods.
         * /// Automatically resolves node matches so base types etc. will be specified directly after the search operation.
         * /// </summary>
         * public static List<AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, IBlockNode block, int nameHash, ISyntaxRegion idObject = null)
         * {
         *      var scan = new SingleNodeNameScan(ctxt, nameHash, idObject);
         *
         *      scan.ScanBlock(block, CodeLocation.Empty, MemberFilter.All);
         *
         *      return scan.matches_types;
         * }*/

        public static List <AbstractType> SearchChildrenAndResolve(ResolutionContext ctxt, DSymbol t, string name, ISyntaxRegion idObject = null)
        {
            return(SearchChildrenAndResolve(ctxt, t, name.GetHashCode(), idObject));
        }
        private static bool DeduceParams(IEnumerable<ISemantic> givenTemplateArguments, 
			bool isMethodCall, 
			ResolutionContext ctxt, 
			DSymbol overload, 
			DNode tplNode, 
			DeducedTypeDictionary deducedTypes)
        {
            bool isLegitOverload = true;

            var paramEnum = tplNode.TemplateParameters.GetEnumerator();

            var args = givenTemplateArguments ?? new List<ISemantic> ();

            var argEnum = args.GetEnumerator();
            foreach (var expectedParam in tplNode.TemplateParameters)
                if (!DeduceParam(ctxt, overload, deducedTypes, argEnum, expectedParam))
                {
                    isLegitOverload = false;
                    break; // Don't check further params if mismatch has been found
                }

            if (!isMethodCall && argEnum.MoveNext())
            {
                // There are too many arguments passed - discard this overload
                isLegitOverload = false;
            }
            return isLegitOverload;
        }
        private static bool DeduceParams(IEnumerable<ISemantic> givenTemplateArguments, 
			bool isMethodCall, 
			ResolverContextStack ctxt, 
			DSymbol overload, 
			DNode tplNode, 
			DeducedTypeDictionary deducedTypes)
        {
            bool isLegitOverload = true;

            var paramEnum = tplNode.TemplateParameters.GetEnumerator();

            var args= givenTemplateArguments == null ? new List<ISemantic>() : givenTemplateArguments;

            if (overload is MemberSymbol && ((MemberSymbol)overload).IsUFCSResult){
                var l = new List<ISemantic>();
                l.Add(overload.Base); // The base stores the first argument('s type)
                l.AddRange(args);
                args = l;
            }

            var argEnum = args.GetEnumerator();
            foreach (var expectedParam in tplNode.TemplateParameters)
                if (!DeduceParam(ctxt, overload, deducedTypes, argEnum, expectedParam))
                {
                    isLegitOverload = false;
                    break; // Don't check further params if mismatch has been found
                }

            if (!isMethodCall && argEnum.MoveNext())
            {
                // There are too many arguments passed - discard this overload
                isLegitOverload = false;
            }
            return isLegitOverload;
        }