Exemplo n.º 1
0
        public static string GeneratePrototype(AbstractType t, int currentParameter = -1, bool isInTemplateArgInsight = false)
        {
            var ms = t as MemberSymbol;

            if (ms != null)
            {
                if (ms.Definition is DVariable)
                {
                    var bt = DResolver.StripAliasSymbol(ms.Base);
                    if (bt is DelegateType)
                    {
                        return(VDServerCompletionDataGenerator.GeneratePrototype(bt as DelegateType, currentParameter));
                    }
                }
                else if (ms.Definition is DMethod)
                {
                    return(VDServerCompletionDataGenerator.GeneratePrototype(ms.Definition as DMethod, isInTemplateArgInsight, currentParameter));
                }
            }
            else if (t is TemplateIntermediateType)
            {
                return(VDServerCompletionDataGenerator.GeneratePrototype(t as TemplateIntermediateType, currentParameter));
            }

            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// http://dlang.org/expression.html#IsExpression
        /// </summary>
        public ISemantic E(IsExpression isExpression)
        {
            if (!eval)
            {
                return(new PrimitiveType(DTokens.Bool));
            }

            bool retTrue = false;

            if (isExpression.TestedType != null)
            {
                var typeToCheck = DResolver.StripAliasSymbol(TypeDeclarationResolver.ResolveSingle(isExpression.TestedType, ctxt));

                if (typeToCheck != null)
                {
                    // case 1, 4
                    if (isExpression.TypeSpecialization == null && isExpression.TypeSpecializationToken == 0)
                    {
                        retTrue = typeToCheck != null;
                    }

                    // The probably most frequented usage of this expression
                    else if (string.IsNullOrEmpty(isExpression.TypeAliasIdentifier))
                    {
                        retTrue = evalIsExpression_NoAlias(isExpression, typeToCheck);
                    }
                    else
                    {
                        retTrue = evalIsExpression_WithAliases(isExpression, typeToCheck);
                    }
                }
            }

            return(new PrimitiveValue(DTokens.Bool, retTrue?1:0, isExpression));
        }
Exemplo n.º 3
0
        ISemantic E(PostfixExpression ex)
        {
            if (ex is PostfixExpression_MethodCall)
            {
                return(E((PostfixExpression_MethodCall)ex, !ctxt.Options.HasFlag(ResolutionOptions.ReturnMethodReferencesOnly)));
            }

            var foreExpr = E(ex.PostfixForeExpression);

            if (foreExpr is AliasedType)
            {
                foreExpr = DResolver.StripAliasSymbol((AbstractType)foreExpr);
            }

            if (foreExpr == null)
            {
                if (eval)
                {
                    return(null);
                }
                else
                {
                    ctxt.LogError(new NothingFoundError(ex.PostfixForeExpression));
                    return(null);
                }
            }

            if (ex is PostfixExpression_Access)
            {
                var r = E((PostfixExpression_Access)ex, foreExpr, true);
                ctxt.CheckForSingleResult(r, ex);
                return(r != null && r.Length != 0 ? r[0] : null);
            }
            else if (ex is PostfixExpression_Increment)
            {
                return(E((PostfixExpression_Increment)ex, foreExpr));
            }
            else if (ex is PostfixExpression_Decrement)
            {
                return(E((PostfixExpression_Decrement)foreExpr));
            }

            // myArray[0]; myArray[0..5];
            // opIndex/opSlice ?
            if (foreExpr is MemberSymbol)
            {
                foreExpr = DResolver.StripMemberSymbols((AbstractType)foreExpr);
            }

            if (ex is PostfixExpression_Slice)
            {
                return(E((PostfixExpression_Slice)ex, foreExpr));
            }
            else if (ex is PostfixExpression_Index)
            {
                return(E((PostfixExpression_Index)ex, foreExpr));
            }

            return(null);
        }
Exemplo n.º 4
0
        AbstractType HandleAccessExpressions(PostfixExpression_Access acc, ResolutionContext 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);
                }
            }

            var accessedMembers = Evaluation.GetAccessedOverloads(acc, ctxt, pfType);

            ctxt.CheckForSingleResult(accessedMembers, acc);

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

            return(null);
        }
Exemplo n.º 5
0
        public static TooltipInformation Generate(AbstractType t, int currentParameter = -1, bool isInTemplateArgInsight = false)
        {
            var ms = t as MemberSymbol;

            if (ms != null)
            {
                if (ms.Definition is DVariable)
                {
                    var bt = DResolver.StripAliasSymbol(ms.Base);
                    if (bt is DelegateType)
                    {
                        return(TooltipInfoGenerator.Generate(bt as DelegateType, currentParameter));
                    }
                }
                else if (ms.Definition is DMethod)
                {
                    return(TooltipInfoGenerator.Generate(ms.Definition as DMethod, isInTemplateArgInsight, currentParameter));
                }
            }
            else if (t is TemplateIntermediateType)
            {
                return(Generate(t as TemplateIntermediateType, currentParameter));
            }

            return(new TooltipInformation());
        }
Exemplo n.º 6
0
        void _th(object pcl_shared)
        {
            var pcl  = (ParseCacheList)pcl_shared;
            var ctxt = new ResolverContextStack(pcl, new ResolverContext {
                ScopedBlock = ast
            });

            // Make it as most performing as possible by avoiding unnecessary base types.
            // Aliases should be analyzed deeper though.
            ctxt.CurrentContext.ContextDependentOptions |=
                ResolutionOptions.StopAfterFirstOverloads |
                ResolutionOptions.DontResolveBaseTypes |                 //TODO: Exactly find out which option can be enabled here. Resolving variables' types is needed sometimes - but only, when highlighting a variable reference is wanted explicitly.
                ResolutionOptions.NoTemplateParameterDeduction |
                ResolutionOptions.ReturnMethodReferencesOnly;

            ISyntaxRegion sr = null;
            int           i  = 0;

            while (curQueueOffset < queueCount)
            {
                // Avoid race condition runtime errors
                lock (_lockObject)
                {
                    i = curQueueOffset;
                    curQueueOffset++;
                }

                // Resolve gotten syntax object
                sr = q[i];
                var sb = ctxt.CurrentContext.ScopedBlock;
                ctxt.CurrentContext.ScopedBlock = DResolver.SearchBlockAt(
                    sb == null || sr.Location <sb.BlockStartLocation || sr.EndLocation> sb.EndLocation ? ast : sb,
                    sr.Location,
                    out ctxt.CurrentContext.ScopedStatement);

                if (sr is PostfixExpression_Access)
                {
                    HandleAccessExpressions((PostfixExpression_Access)sr, ctxt);
                }
                else
                {
                    AbstractType t = null;
                    if (sr is IExpression)
                    {
                        t = DResolver.StripAliasSymbol(Evaluation.EvaluateType((IExpression)sr, ctxt));
                    }
                    else if (sr is ITypeDeclaration)
                    {
                        t = DResolver.StripAliasSymbol(TypeDeclarationResolver.ResolveSingle((ITypeDeclaration)sr, ctxt));
                    }

                    // Enter into the result list
                    HandleResult(sr, t);
                }
            }
        }
Exemplo n.º 7
0
        ISemantic E(NewExpression nex)
        {
            // http://www.d-programming-language.org/expression.html#NewExpression
            ISemantic[] possibleTypes = null;

            if (nex.Type is IdentifierDeclaration)
            {
                possibleTypes = TypeDeclarationResolver.Resolve((IdentifierDeclaration)nex.Type, ctxt, filterForTemplateArgs: false);
            }
            else
            {
                possibleTypes = TypeDeclarationResolver.Resolve(nex.Type, ctxt);
            }

            var ctors = new Dictionary <DMethod, TemplateIntermediateType>();

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

            foreach (var t in possibleTypes)
            {
                var ct = DResolver.StripAliasSymbol(t as AbstractType) as TemplateIntermediateType;
                if (ct != null &&
                    !ct.Definition.ContainsAttribute(DTokens.Abstract))
                {
                    foreach (var ctor in GetConstructors(ct))
                    {
                        ctors.Add(ctor, ct);
                    }
                }
            }

            MemberSymbol finalCtor = null;

            var kvArray = ctors.ToArray();

            /*
             * TODO: Determine argument types and filter out ctor overloads.
             */

            if (kvArray.Length != 0)
            {
                finalCtor = new MemberSymbol(kvArray[0].Key, kvArray[0].Value, nex);
            }
            else if (possibleTypes.Length != 0)
            {
                return(AbstractType.Get(possibleTypes[0]));
            }

            return(finalCtor);
        }
Exemplo n.º 8
0
        public void EponymousTemplates()
        {
            var          ctxt = ResolutionTests.CreateDefCtxt(@"module B;
alias Tuple(T...) = T;
alias Tup = Tuple!(int, float, string);

enum isIntOrFloat(F) = is(F == int) || is(F == float);
");
            IExpression  x;
            ISymbolValue v;
            AbstractType t;

            x = DParser.ParseExpression("isIntOrFloat!(Tup[0])");
            v = Evaluation.EvaluateValue(x, ctxt);
            Assert.That(v, Is.TypeOf(typeof(PrimitiveValue)));
            Assert.That((v as PrimitiveValue).Value, Is.Not.EqualTo(0m));

            DToken tk;
            var    td = DParser.ParseBasicType("Tuple!(int, float, string)", out tk);

            //t = TypeDeclarationResolver.ResolveSingle (td, ctxt);
            //Assert.That (t, Is.TypeOf(typeof(MemberSymbol)));
            //Assert.That ((t as MemberSymbol).Base, Is.TypeOf(typeof(DTuple)));

            x = DParser.ParseExpression("Tup[0]");
            t = ExpressionTypeEvaluation.EvaluateType(x, ctxt);
            Assert.That(t, Is.TypeOf(typeof(PrimitiveType)));

            x = DParser.ParseExpression("Tup[1]");
            t = ExpressionTypeEvaluation.EvaluateType(x, ctxt);
            Assert.That(t, Is.TypeOf(typeof(PrimitiveType)));

            x = DParser.ParseExpression("Tup[2]");
            t = DResolver.StripAliasSymbol(ExpressionTypeEvaluation.EvaluateType(x, ctxt));
            Assert.That(t, Is.TypeOf(typeof(ArrayType)));


            x = DParser.ParseExpression("isIntOrFloat!int");
            v = Evaluation.EvaluateValue(x, ctxt);
            Assert.That(v, Is.TypeOf(typeof(PrimitiveValue)));
            Assert.That((v as PrimitiveValue).Value, Is.Not.EqualTo(0m));

            x = DParser.ParseExpression("isIntOrFloat!float");
            v = Evaluation.EvaluateValue(x, ctxt);
            Assert.That(v, Is.TypeOf(typeof(PrimitiveValue)));
            Assert.That((v as PrimitiveValue).Value, Is.Not.EqualTo(0m));

            x = DParser.ParseExpression("isIntOrFloat!string");
            v = Evaluation.EvaluateValue(x, ctxt);
            Assert.That(v, Is.TypeOf(typeof(PrimitiveValue)));
            Assert.That((v as PrimitiveValue).Value, Is.EqualTo(0m));
        }
Exemplo n.º 9
0
 public static AbstractType ResolveTraitArgument(ResolutionContext ctxt, TraitsArgument arg)
 {
     if (arg.Type != null)
     {
         return(TypeDeclarationResolver.ResolveSingle(arg.Type, ctxt));
     }
     else if (arg.AssignExpression != null)
     {
         return(DResolver.StripAliasSymbol(EvaluateType(arg.AssignExpression, ctxt)));
     }
     else
     {
         return(null);
     }
 }
Exemplo n.º 10
0
 AbstractType E(TraitsArgument arg, TraitsExpression te)
 {
     if (arg.Type != null)
     {
         return(TypeDeclarationResolver.ResolveSingle(arg.Type, ctxt));
     }
     else if (arg.AssignExpression != null)
     {
         return(DResolver.StripAliasSymbol(EvaluateType(arg.AssignExpression, ctxt)));
     }
     else
     {
         EvalError(te, "Argument must be a type or an expression!");
         return(null);
     }
 }
Exemplo n.º 11
0
        AbstractType EvalForeExpression(PostfixExpression ex)
        {
            var foreExpr = ex.PostfixForeExpression != null?ex.PostfixForeExpression.Accept(this) : null;

            if (foreExpr is AliasedType)
            {
                foreExpr = DResolver.StripAliasSymbol(foreExpr);
            }

            if (foreExpr == null)
            {
                ctxt.LogError(new NothingFoundError(ex.PostfixForeExpression));
            }

            return(foreExpr);
        }
        public static ArrayType GetStringType(ResolutionContext ctxt, LiteralSubformat fmt = LiteralSubformat.Utf8)
        {
            ArrayType _t = null;

            if (ctxt != null)
            {
                var obj = ctxt.ParseCache.LookupModuleName("object").FirstOrDefault();

                if (obj != null)
                {
                    string strType = fmt == LiteralSubformat.Utf32 ? "dstring" :
                                     fmt == LiteralSubformat.Utf16 ? "wstring" :
                                     "string";

                    var strNode = obj[strType];

                    if (strNode != null)
                    {
                        foreach (var n in strNode)
                        {
                            _t = DResolver.StripAliasSymbol(TypeDeclarationResolver.HandleNodeMatch(n, ctxt)) as ArrayType;
                            if (_t != null)
                            {
                                break;
                            }
                        }
                    }
                }
            }

            if (_t == null)
            {
                var ch = fmt == LiteralSubformat.Utf32 ? DTokens.Dchar :
                         fmt == LiteralSubformat.Utf16 ? DTokens.Wchar : DTokens.Char;

                _t = new ArrayType(new PrimitiveType(ch, DTokens.Immutable),
                                   new ArrayDecl
                {
                    ValueType = new MemberFunctionAttributeDecl(DTokens.Immutable)
                    {
                        InnerType = new DTokenDeclaration(ch)
                    }
                });
            }

            return(_t);
        }
        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);
        }
Exemplo n.º 14
0
        public void AliasedTypeTuple()
        {
            var          ctxt = ResolutionTests.CreateDefCtxt(@"module A;
template Tuple(T...) { alias Tuple = T; }
alias Tup = Tuple!(int, float, string);

template isIntOrFloat(T)
{
    static if (is(T == int) || is(T == float))
        enum isIntOrFloat = true;
    else
        enum isIntOrFloat = false;
}
");
            IExpression  x;
            ISymbolValue v;
            AbstractType t;

            x = DParser.ParseExpression("Tup[2]");
            t = DResolver.StripAliasSymbol(ExpressionTypeEvaluation.EvaluateType(x, ctxt));
            Assert.That(t, Is.TypeOf(typeof(ArrayType)));

            x = DParser.ParseExpression("isIntOrFloat!(Tup[2])");
            v = Evaluation.EvaluateValue(x, ctxt);
            Assert.That(v, Is.TypeOf(typeof(PrimitiveValue)));
            Assert.That((v as PrimitiveValue).Value, Is.EqualTo(0m));

            x = DParser.ParseExpression("Tup[0]");
            t = ExpressionTypeEvaluation.EvaluateType(x, ctxt);
            Assert.That(t, Is.TypeOf(typeof(PrimitiveType)));

            x = DParser.ParseExpression("Tup[1]");
            t = ExpressionTypeEvaluation.EvaluateType(x, ctxt);
            Assert.That(t, Is.TypeOf(typeof(PrimitiveType)));

            x = DParser.ParseExpression("isIntOrFloat!(Tup[0])");
            v = Evaluation.EvaluateValue(x, ctxt);
            Assert.That(v, Is.TypeOf(typeof(PrimitiveValue)));
            Assert.That((v as PrimitiveValue).Value, Is.Not.EqualTo(0m));
        }
Exemplo n.º 15
0
        protected override void BuildCompletionDataInternal(IEditorData Editor, char enteredChar)
        {
            ctxt = ResolutionContext.Create(Editor.ParseCache, new ConditionalCompilationFlags(Editor), ScopedBlock, ScopedStatement);
            ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.ReturnMethodReferencesOnly;

            var ex = AccessExpression.AccessExpression == null ? AccessExpression.PostfixForeExpression : AccessExpression;

            var r = DResolver.StripAliasSymbol(Evaluation.EvaluateType(ex, ctxt));

            if (r == null)             //TODO: Add after-space list creation when an unbound . (Dot) was entered which means to access the global scope
            {
                return;
            }

            BuildCompletionData(r, ScopedBlock);

            if (CompletionOptions.Instance.ShowUFCSItems && (MemberFilter & MemberFilter.Methods) != 0 &&
                !(r is UserDefinedType || r is PrimitiveType || r is PackageSymbol || r is ModuleSymbol))
            {
                UFCSCompletionProvider.Generate(r, ctxt, Editor, CompletionDataGenerator);
            }
        }
Exemplo n.º 16
0
        protected override void BuildCompletionDataInternal(IEditorData Editor, char enteredChar)
        {
            ed   = Editor;
            ctxt = ResolutionContext.Create(Editor.ParseCache, new ConditionalCompilationFlags(Editor), ScopedBlock, ScopedStatement);
            ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.ReturnMethodReferencesOnly;

            AbstractType t;

            if (AccessExpression is IExpression)
            {
                t = ExpressionTypeEvaluation.EvaluateType(AccessExpression as IExpression, ctxt);
            }
            else if (AccessExpression is ITypeDeclaration)
            {
                t = TypeDeclarationResolver.ResolveSingle(AccessExpression as ITypeDeclaration, ctxt);
            }
            else
            {
                return;
            }

            t = DResolver.StripAliasSymbol(t);

            if (t == null)             //TODO: Add after-space list creation when an unbound . (Dot) was entered which means to access the global scope
            {
                return;
            }

            isVariableInstance = false;

            if (t.DeclarationOrExpressionBase is ITypeDeclaration)
            {
                isVariableInstance |= (t.DeclarationOrExpressionBase as ITypeDeclaration).ExpressesVariableAccess;
            }

            t.Accept(this);
        }
Exemplo n.º 17
0
        public static AbstractType[] GetUnfilteredMethodOverloads(IExpression foreExpression, ResolutionContext ctxt, IExpression supExpression = null)
        {
            AbstractType[] overloads = null;

            if (foreExpression is TemplateInstanceExpression)
            {
                overloads = Evaluation.GetOverloads(foreExpression as TemplateInstanceExpression, ctxt, null);
            }
            else if (foreExpression is IdentifierExpression)
            {
                overloads = Evaluation.GetOverloads(foreExpression as IdentifierExpression, ctxt, false);
            }
            else if (foreExpression is PostfixExpression_Access)
            {
                overloads = Evaluation.GetAccessedOverloads((PostfixExpression_Access)foreExpression, ctxt, null, false);
            }
            else if (foreExpression is TokenExpression)
            {
                overloads = GetResolvedConstructorOverloads((TokenExpression)foreExpression, ctxt);
            }
            else
            {
                overloads = new[] { Evaluation.EvaluateType(foreExpression, ctxt) }
            };

            var  l          = new List <AbstractType>();
            bool staticOnly = true;

            foreach (var ov in DResolver.StripAliasSymbols(overloads))
            {
                var t = ov;
                if (ov is MemberSymbol)
                {
                    var ms = ov as MemberSymbol;
                    if (ms.Definition is Dom.DMethod)
                    {
                        l.Add(ms);
                        continue;
                    }

                    staticOnly = false;
                    t          = DResolver.StripAliasSymbol(ms.Base);
                }

                if (t is TemplateIntermediateType)
                {
                    var tit = t as TemplateIntermediateType;

                    var m = TypeDeclarationResolver.HandleNodeMatches(
                        GetOpCalls(tit, staticOnly), ctxt,
                        null, supExpression ?? foreExpression);

                    /*
                     * On structs, there must be a default () constructor all the time.
                     * If there are (other) constructors in structs, the explicit member initializer constructor is not
                     * provided anymore. This will be handled in the GetConstructors() method.
                     * If there are opCall overloads, canCreateeExplicitStructCtor overrides the ctor existence check in GetConstructors()
                     * and enforces that the explicit ctor will not be generated.
                     * An opCall overload with no parameters supersedes the default ctor.
                     */
                    var canCreateExplicitStructCtor = m == null || m.Length == 0;

                    if (!canCreateExplicitStructCtor)
                    {
                        l.AddRange(m);
                    }

                    m = TypeDeclarationResolver.HandleNodeMatches(
                        GetConstructors(tit, canCreateExplicitStructCtor), ctxt,
                        null, supExpression ?? foreExpression);

                    if (m != null && m.Length != 0)
                    {
                        l.AddRange(m);
                    }
                }
                else
                {
                    l.Add(ov);
                }
            }

            return(l.ToArray());
        }
Exemplo n.º 18
0
        bool HandleAliasThisDeclarations(TemplateIntermediateType tit, MemberFilter vis)
        {
            bool pop;
            var  ch = tit.Definition [DVariable.AliasThisIdentifierHash];

            if (ch != null)
            {
                foreach (DVariable aliasDef in ch)
                {
                    if (MatchesCompilationConditions(aliasDef) ||
                        aliasDef.Type == null)
                    {
                        continue;
                    }

                    pop = ctxt.ScopedBlock != tit.Definition;
                    if (pop)
                    {
                        ctxt.PushNewScope(tit.Definition);
                    }

                    // Resolve the aliased symbol and expect it to be a member symbol(?).
                    //TODO: Check if other cases are allowed as well!
                    var aliasedSymbol = DResolver.StripAliasSymbol(TypeDeclarationResolver.ResolveSingle(aliasDef.Type, ctxt));
                    var aliasedMember = aliasedSymbol as MemberSymbol;

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

                    if (aliasedMember == null)
                    {
                        if (aliasedSymbol != null)
                        {
                            ctxt.LogError(aliasDef, "Aliased type from 'alias this' definition is expected to be a type instance, not " + aliasedSymbol.ToString() + "!");
                        }

                        continue;
                    }

                    /*
                     * The aliased member's type can be everything!
                     */
                    aliasedSymbol = aliasedMember.Base;

                    foreach (var statProp in StaticProperties.ListProperties(aliasedSymbol))
                    {
                        if (HandleItem(statProp))
                        {
                            return(true);
                        }
                    }

                    /** TODO: Visit ufcs recommendations and other things that
                     * become added in e.g. MemberCompletionProvider
                     */

                    var tit_ = aliasedSymbol as TemplateIntermediateType;
                    if (tit_ != null)
                    {
                        pop = !ctxt.ScopedBlockIsInNodeHierarchy(tit_.Definition);
                        if (pop)
                        {
                            ctxt.PushNewScope(tit_.Definition);
                        }
                        ctxt.CurrentContext.IntroduceTemplateParameterTypes(tit_);
                        var r = DeepScanClass(tit_, vis, true);
                        if (pop)
                        {
                            ctxt.Pop();
                        }
                        else
                        {
                            ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(tit_);
                        }
                        if (r)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Exemplo n.º 19
0
        ISemantic E(PostfixExpression_MethodCall call, bool returnBaseTypeOnly = true)
        {
            // Deduce template parameters later on
            AbstractType[]             baseExpression;
            ISymbolValue               baseValue;
            TemplateInstanceExpression tix;

            GetRawCallOverloads(call, out baseExpression, out baseValue, out tix);

            var methodOverloads = new List <AbstractType>();

            #region Search possible methods, opCalls or delegates that could be called
            bool requireStaticItems = true;             //TODO: What if there's an opCall and a foreign method at the same time? - and then this variable would be bullshit
            IEnumerable <AbstractType> scanResults = DResolver.StripAliasSymbols(baseExpression);
            var nextResults = new List <AbstractType>();

            while (scanResults != null)
            {
                foreach (var b in scanResults)
                {
                    if (b is MemberSymbol)
                    {
                        var mr = (MemberSymbol)b;

                        if (mr.Definition is DMethod)
                        {
                            methodOverloads.Add(mr);
                            continue;
                        }
                        else if (mr.Definition is DVariable)
                        {
                            // If we've got a variable here, get its base type/value reference
                            if (eval)
                            {
                                var dgVal = ValueProvider[(DVariable)mr.Definition] as DelegateValue;

                                if (dgVal != null)
                                {
                                    nextResults.Add(dgVal.Definition);
                                    continue;
                                }
                                else
                                {
                                    EvalError(call, "Variable must be a delegate, not anything else", mr);
                                    return(null);
                                }
                            }
                            else
                            {
                                var bt = DResolver.StripAliasSymbol(mr.Base ?? TypeDeclarationResolver.ResolveSingle(mr.Definition.Type, ctxt));

                                // Must be of type delegate
                                if (bt is DelegateType)
                                {
                                    //TODO: Ensure that there's no further overload - inform the user elsewise

                                    if (returnBaseTypeOnly)
                                    {
                                        return(bt);
                                    }
                                    else
                                    {
                                        return(new MemberSymbol(mr.Definition, bt, mr.DeclarationOrExpressionBase));
                                    }
                                }
                                else
                                {
                                    /*
                                     * If mr.Node is not a method, so e.g. if it's a variable
                                     * pointing to a delegate
                                     *
                                     * class Foo
                                     * {
                                     *	string opCall() {  return "asdf";  }
                                     * }
                                     *
                                     * Foo f=new Foo();
                                     * f(); -- calls opCall, opCall is not static
                                     */
                                    nextResults.Add(bt);
                                    requireStaticItems = false;
                                }
                                //TODO: Can other types work as function/are callable?
                            }
                        }
                    }
                    else if (b is DelegateType)
                    {
                        var dg = (DelegateType)b;

                        /*
                         * int a = delegate(x) { return x*2; } (12); // a is 24 after execution
                         * auto dg=delegate(x) {return x*3;};
                         * int b = dg(4);
                         */

                        if (dg.IsFunctionLiteral)
                        {
                            methodOverloads.Add(dg);
                        }
                        else
                        {
                            // If it's just wanted to pass back the delegate's return type, skip the remaining parts of this method.
                            if (eval)
                            {
                                EvalError(call, "TODO", dg);
                                return(null);
                            }
                            //TODO
                            //if(returnBaseTypeOnly)
                            //TODO: Check for multiple definitions. Also, make a parameter-argument check to inform the user about wrong arguments.
                            return(dg);
                        }
                    }
                    else if (b is ClassType || b is StructType)
                    {
                        var tit = (TemplateIntermediateType)b;

                        /*
                         * auto a = MyStruct(); -- opCall-Overloads can be used
                         */
                        var classDef = tit.Definition;

                        if (classDef == null)
                        {
                            continue;
                        }

                        foreach (var i in GetOpCalls(tit, requireStaticItems))
                        {
                            methodOverloads.Add(TypeDeclarationResolver.HandleNodeMatch(i, ctxt, b, call) as MemberSymbol);
                        }

                        /*
                         * Every struct can contain a default ctor:
                         *
                         * struct S { int a; bool b; }
                         *
                         * auto s = S(1,true); -- ok
                         * auto s2= new S(2,false); -- error, no constructor found!
                         */
                        if (b is StructType && methodOverloads.Count == 0)
                        {
                            //TODO: Deduce parameters
                            return(b);
                        }
                    }

                    /*
                     * If the overload is a template, it quite exclusively means that we'll handle a method that is the only
                     * child inside a template + that is named as the template.
                     */
                    else if (b is TemplateType)
                    {
                        methodOverloads.Add(b);
                    }
                }

                scanResults = nextResults.Count == 0 ? null : nextResults.ToArray();
                nextResults.Clear();
            }
            #endregion

            if (methodOverloads.Count == 0)
            {
                return(null);
            }

            // Get all arguments' types
            var  callArguments   = new List <ISemantic>();
            bool hasNonFinalArgs = false;

            if (call.Arguments != null)
            {
                foreach (var arg in call.Arguments)
                {
                    callArguments.Add(E(arg));
                }
            }

            #region If explicit template type args were given, try to associate them with each overload
            if (tix != null)
            {
                var args             = TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt, out hasNonFinalArgs);
                var deducedOverloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(methodOverloads, args, true, ctxt, hasNonFinalArgs);
                methodOverloads.Clear();
                if (deducedOverloads != null)
                {
                    methodOverloads.AddRange(deducedOverloads);
                }
            }
            #endregion

            #region Filter by parameter-argument comparison
            var  argTypeFilteredOverloads   = new List <AbstractType>();
            bool hasHandledUfcsResultBefore = false;

            foreach (var ov in methodOverloads)
            {
                if (ov is MemberSymbol)
                {
                    var ms = ov as MemberSymbol;
                    var dm = ms.Definition as DMethod;

                    if (dm != null)
                    {
                        // In the case of an ufcs, insert the first argument into the CallArguments list
                        if (ms.IsUFCSResult && !hasHandledUfcsResultBefore)
                        {
                            callArguments.Insert(0, eval ? baseValue as ISemantic : ((MemberSymbol)baseExpression[0]).FirstArgument);
                            hasHandledUfcsResultBefore = true;
                        }
                        else if (!ms.IsUFCSResult && hasHandledUfcsResultBefore)                         // In the rare case of having a ufcs result occuring _after_ a normal member result, remove the initial arg again
                        {
                            callArguments.RemoveAt(0);
                            hasHandledUfcsResultBefore = false;
                        }

                        var deducedTypeDict = new DeducedTypeDictionary(ms);
                        if (dm.TemplateParameters != null)
                        {
                            foreach (var tpar in dm.TemplateParameters)
                            {
                                if (!deducedTypeDict.ContainsKey(tpar.NameHash))
                                {
                                    deducedTypeDict[tpar.NameHash] = null;
                                }
                            }
                        }
                        var templateParamDeduction = new TemplateParameterDeduction(deducedTypeDict, ctxt);

                        int  currentArg = 0;
                        bool add        = true;
                        if (callArguments.Count > 0 || dm.Parameters.Count > 0)
                        {
                            for (int i = 0; i < dm.Parameters.Count; i++)
                            {
                                var paramType = dm.Parameters[i].Type;

                                // Handle the usage of tuples: Tuples may only be used as as-is, so not as an array, pointer or in a modified way..
                                if (paramType is IdentifierDeclaration &&
                                    TryHandleMethodArgumentTuple(ref add, callArguments, dm, deducedTypeDict, i, ref currentArg))
                                {
                                    continue;
                                }
                                else if (currentArg < callArguments.Count)
                                {
                                    if (!templateParamDeduction.HandleDecl(null, paramType, callArguments[currentArg++]))
                                    {
                                        add = false;
                                        break;
                                    }
                                }
                                else
                                {
                                    // If there are more parameters than arguments given, check if the param has default values
                                    if (!(dm.Parameters[i] is DVariable) || (dm.Parameters[i] as DVariable).Initializer == null)
                                    {
                                        add = false;
                                        break;
                                    }
                                    // Assume that all further method parameters do have default values - and don't check further parameters
                                    break;
                                }
                            }
                        }

                        // If type params were unassigned, try to take the defaults
                        if (add && dm.TemplateParameters != null)
                        {
                            foreach (var tpar in dm.TemplateParameters)
                            {
                                if (deducedTypeDict[tpar.NameHash] == null)
                                {
                                    add = templateParamDeduction.Handle(tpar, null);
                                    if (!add)
                                    {
                                        if (hasNonFinalArgs)
                                        {
                                            deducedTypeDict[tpar.NameHash] = new TemplateParameterSymbol(tpar, null);
                                            add = true;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                        if (add && (deducedTypeDict.AllParamatersSatisfied || hasNonFinalArgs))
                        {
                            ms.DeducedTypes = deducedTypeDict.ToReadonly();
                            ctxt.CurrentContext.IntroduceTemplateParameterTypes(ms);

                            var bt = ms.Base ?? TypeDeclarationResolver.GetMethodReturnType(dm, ctxt);

                            ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(ms);

                            if (eval || !returnBaseTypeOnly)
                            {
                                argTypeFilteredOverloads.Add(ms.Base == null ? new MemberSymbol(dm, bt, ms.DeclarationOrExpressionBase, ms.DeducedTypes) : ms);
                            }
                            else
                            {
                                argTypeFilteredOverloads.Add(bt);
                            }
                        }
                    }
                }
                else if (ov is DelegateType)
                {
                    var dg = (DelegateType)ov;
                    var bt = TypeDeclarationResolver.GetMethodReturnType(dg, ctxt);

                    //TODO: Param-Arg check

                    if (!eval || returnBaseTypeOnly)
                    {
                        argTypeFilteredOverloads.Add(bt);
                    }
                    else
                    {
                        argTypeFilteredOverloads.Add(new DelegateType(bt, dg.DeclarationOrExpressionBase as FunctionLiteral, dg.Parameters));
                    }
                }
            }
            #endregion

            if (eval)
            {
                // Convert ISemantic[] to ISymbolValue[]
                var args = new List <ISymbolValue>(callArguments.Count);

                foreach (var a in callArguments)
                {
                    args.Add(a as ISymbolValue);
                }

                // Execute/Evaluate the variable contents etc.
                return(TryDoCTFEOrGetValueRefs(argTypeFilteredOverloads.ToArray(), call.PostfixForeExpression, true, args.ToArray()));
            }
            else
            {
                // Check if one overload remains and return that one.
                ctxt.CheckForSingleResult(argTypeFilteredOverloads.ToArray(), call);
                return(argTypeFilteredOverloads.Count != 0 ? argTypeFilteredOverloads[0] : null);
            }
        }
Exemplo n.º 20
0
        ISemantic E(PostfixExpression_MethodCall call, bool returnBaseTypeOnly = true)
        {
            // Deduce template parameters later on
            AbstractType[]             baseExpression = null;
            ISymbolValue               baseValue      = null;
            TemplateInstanceExpression tix            = null;
            bool isUFCSFunction = false;

            GetRawCallOverloads(call, out baseExpression, out baseValue, out tix, out isUFCSFunction);

            var methodOverloads = new List <AbstractType>();

            #region Search possible methods, opCalls or delegates that could be called
            bool requireStaticItems = true;             //TODO: What if there's an opCall and a foreign method at the same time? - and then this variable would be bullshit
            IEnumerable <AbstractType> scanResults = DResolver.StripAliasSymbols(baseExpression);
            var nextResults = new List <AbstractType>();

            while (scanResults != null)
            {
                foreach (var b in scanResults)
                {
                    if (b is MemberSymbol)
                    {
                        var mr = (MemberSymbol)b;

                        if (mr.Definition is DMethod)
                        {
                            methodOverloads.Add(mr);
                            continue;
                        }
                        else if (mr.Definition is DVariable)
                        {
                            // If we've got a variable here, get its base type/value reference
                            if (eval)
                            {
                                var dgVal = ValueProvider[(DVariable)mr.Definition] as DelegateValue;

                                if (dgVal != null)
                                {
                                    nextResults.Add(dgVal.Definition);
                                    continue;
                                }
                                else
                                {
                                    throw new EvaluationException(call, "Variable must be a delegate, not anything else", mr);
                                }
                            }
                            else
                            {
                                var bt = DResolver.StripAliasSymbol(mr.Base ?? TypeDeclarationResolver.ResolveSingle(mr.Definition.Type, ctxt));

                                // Must be of type delegate
                                if (bt is DelegateType)
                                {
                                    //TODO: Ensure that there's no further overload - inform the user elsewise

                                    if (returnBaseTypeOnly)
                                    {
                                        return(bt);
                                    }
                                    else
                                    {
                                        return(new MemberSymbol(mr.Definition, bt, mr.DeclarationOrExpressionBase));
                                    }
                                }
                                else
                                {
                                    /*
                                     * If mr.Node is not a method, so e.g. if it's a variable
                                     * pointing to a delegate
                                     *
                                     * class Foo
                                     * {
                                     *	string opCall() {  return "asdf";  }
                                     * }
                                     *
                                     * Foo f=new Foo();
                                     * f(); -- calls opCall, opCall is not static
                                     */
                                    nextResults.Add(bt);
                                    requireStaticItems = false;
                                }
                                //TODO: Can other types work as function/are callable?
                            }
                        }
                    }
                    else if (b is DelegateType)
                    {
                        var dg = (DelegateType)b;

                        /*
                         * int a = delegate(x) { return x*2; } (12); // a is 24 after execution
                         * auto dg=delegate(x) {return x*3;};
                         * int b = dg(4);
                         */

                        if (dg.IsFunctionLiteral)
                        {
                            methodOverloads.Add(dg);
                        }
                        else
                        {
                            // If it's just wanted to pass back the delegate's return type, skip the remaining parts of this method.
                            if (eval)
                            {
                                throw new EvaluationException(call, "TODO", dg);
                            }
                            //TODO
                            //if(returnBaseTypeOnly)
                            //TODO: Check for multiple definitions. Also, make a parameter-argument check to inform the user about wrong arguments.
                            return(dg);
                        }
                    }
                    else if (b is ClassType)
                    {
                        /*
                         * auto a = MyStruct(); -- opCall-Overloads can be used
                         */
                        var classDef = ((ClassType)b).Definition;

                        if (classDef == null)
                        {
                            continue;
                        }

                        foreach (var i in classDef)
                        {
                            if (i.Name == "opCall" && i is DMethod && (!requireStaticItems || (i as DNode).IsStatic))
                            {
                                methodOverloads.Add(TypeDeclarationResolver.HandleNodeMatch(i, ctxt, b, call) as MemberSymbol);
                            }
                        }
                    }

                    /*
                     * Every struct can contain a default ctor:
                     *
                     * struct S { int a; bool b; }
                     *
                     * auto s = S(1,true); -- ok
                     * auto s2= new S(2,false); -- error, no constructor found!
                     */
                    else if (b is StructType && methodOverloads.Count == 0)
                    {
                        //TODO: Deduce parameters
                        return(b);
                    }

                    /*
                     * If the overload is a template, it quite exclusively means that we'll handle a method that is the only
                     * child inside a template + that is named as the template.
                     */
                    else if (b is TemplateType &&
                             ImplicitTemplateProperties.ContainsEquallyNamedChildrenOnly(((TemplateType)b).Definition))
                    {
                        methodOverloads.Add(b);
                    }
                }

                scanResults = nextResults.Count == 0 ? null : nextResults.ToArray();
                nextResults.Clear();
            }
            #endregion

            if (methodOverloads.Count == 0)
            {
                return(null);
            }

            // Get all arguments' types
            var callArguments = new List <ISemantic>();

            // If it's sure that we got a ufcs call here, add the base expression's type as first argument type
            if (isUFCSFunction)
            {
                callArguments.Add(eval ? (ISemantic)baseValue : ((MemberSymbol)baseExpression[0]).Base);
            }

            if (call.Arguments != null)
            {
                foreach (var arg in call.Arguments)
                {
                    callArguments.Add(E(arg));
                }
            }

            #region Deduce template parameters and filter out unmatching overloads
            // First add optionally given template params
            // http://dlang.org/template.html#function-templates
            var tplParamDeductionArguments = tix == null ?
                                             new List <ISemantic>() :
                                             TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt);

            // Then add the arguments[' member types]
            foreach (var arg in callArguments)
            {
                if (arg is VariableValue)
                {
                    tplParamDeductionArguments.Add(ValueProvider[((VariableValue)arg).Variable]);
                }
                else if (arg is AbstractType)
                {
                    tplParamDeductionArguments.Add(DResolver.StripMemberSymbols((AbstractType)arg));
                }
                else
                {
                    tplParamDeductionArguments.Add(arg);
                }
            }

            var templateParamFilteredOverloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(
                methodOverloads,
                tplParamDeductionArguments.Count > 0 ? tplParamDeductionArguments.ToArray() : null,
                true, ctxt);
            #endregion

            #region Filter by parameter-argument comparison
            var argTypeFilteredOverloads = new List <AbstractType>();

            if (templateParamFilteredOverloads != null)
            {
                foreach (var ov in templateParamFilteredOverloads)
                {
                    if (ov is MemberSymbol)
                    {
                        var  ms  = (MemberSymbol)ov;
                        var  dm  = ms.Definition as DMethod;
                        bool add = false;

                        if (dm != null)
                        {
                            ctxt.CurrentContext.IntroduceTemplateParameterTypes(ms);

                            add = false;

                            if (callArguments.Count == 0 && dm.Parameters.Count == 0)
                            {
                                add = true;
                            }
                            else
                            {
                                for (int i = 0; i < dm.Parameters.Count; i++)
                                {
                                    var paramType = TypeDeclarationResolver.ResolveSingle(dm.Parameters[i].Type, ctxt);

                                    // TODO: Expression tuples & variable argument lengths
                                    if (i >= callArguments.Count ||
                                        !ResultComparer.IsImplicitlyConvertible(callArguments[i], paramType, ctxt))
                                    {
                                        continue;
                                    }

                                    add = true;
                                }
                            }

                            if (add)
                            {
                                var bt = ms.Base ?? TypeDeclarationResolver.GetMethodReturnType(dm, ctxt);

                                if (returnBaseTypeOnly)
                                {
                                    argTypeFilteredOverloads.Add(bt);
                                }
                                else
                                {
                                    argTypeFilteredOverloads.Add(ms.Base == null ? new MemberSymbol(dm, bt, ms.DeclarationOrExpressionBase, ms.DeducedTypes) : ms);
                                }
                            }

                            ctxt.CurrentContext.RemoveParamTypesFromPreferredLocals(ms);
                        }
                    }
                    else if (ov is DelegateType)
                    {
                        var dg = (DelegateType)ov;
                        var bt = TypeDeclarationResolver.GetMethodReturnType(dg, ctxt);

                        //TODO: Param-Arg check
                        if (returnBaseTypeOnly)
                        {
                            argTypeFilteredOverloads.Add(bt);
                        }
                        else
                        {
                            argTypeFilteredOverloads.Add(new DelegateType(bt, dg.DeclarationOrExpressionBase as FunctionLiteral, dg.Parameters));
                        }
                    }
                }
            }
            #endregion

            if (eval)
            {
                // Convert ISemantic[] to ISymbolValue[]
                var args = new List <ISymbolValue>(callArguments.Count);

                foreach (var a in callArguments)
                {
                    args.Add(a as ISymbolValue);
                }

                // Execute/Evaluate the variable contents etc.
                return(TryDoCTFEOrGetValueRefs(argTypeFilteredOverloads.ToArray(), call.PostfixForeExpression, true, args.ToArray()));
            }
            else
            {
                // Check if one overload remains and return that one.
                ctxt.CheckForSingleResult(argTypeFilteredOverloads.ToArray(), call);
                return(argTypeFilteredOverloads != null && argTypeFilteredOverloads.Count != 0 ?
                       argTypeFilteredOverloads[0] : null);
            }
        }
        public static List <AbstractType> EvalMethodCall(AbstractType[] baseExpression, ISymbolValue baseValue, TemplateInstanceExpression tix,
                                                         ResolutionContext ctxt,
                                                         PostfixExpression_MethodCall call, out List <ISemantic> callArguments, out ISymbolValue delegateValue,
                                                         bool returnBaseTypeOnly, AbstractSymbolValueProvider ValueProvider = null)
        {
            //TODO: Refactor this crap!

            delegateValue = null;
            callArguments = null;

            var methodOverloads = new List <AbstractType>();

            #region Search possible methods, opCalls or delegates that could be called
            bool requireStaticItems = true;             //TODO: What if there's an opCall and a foreign method at the same time? - and then this variable would be bullshit
            IEnumerable <AbstractType> scanResults = DResolver.StripAliasSymbols(baseExpression);
            var nextResults = new List <AbstractType>();

            while (scanResults != null)
            {
                foreach (var b in scanResults)
                {
                    if (b is TemplateParameterSymbol)
                    {
                        nextResults.Add((b as TemplateParameterSymbol).Base);
                    }
                    else if (b is MemberSymbol)
                    {
                        var mr = (MemberSymbol)b;

                        if (mr.Definition is DMethod)
                        {
                            methodOverloads.Add(mr);
                            continue;
                        }
                        else if (mr.Definition is DVariable)
                        {
                            // If we've got a variable here, get its base type/value reference
                            if (ValueProvider != null)
                            {
                                var dgVal = ValueProvider[(DVariable)mr.Definition] as DelegateValue;

                                if (dgVal != null)
                                {
                                    nextResults.Add(dgVal.Definition);
                                    continue;
                                }
                                else
                                {
                                    ValueProvider.LogError(call, "Variable must be a delegate, not anything else");
                                    return(null);
                                }
                            }
                            else
                            {
                                var bt = DResolver.StripAliasSymbol(mr.Base ?? TypeDeclarationResolver.ResolveSingle(mr.Definition.Type, ctxt));

                                // Must be of type delegate
                                if (bt is DelegateType)
                                {
                                    var ret = HandleCallDelegateType(ValueProvider, bt as DelegateType, methodOverloads, returnBaseTypeOnly);
                                    if (ret is ISymbolValue)
                                    {
                                        delegateValue = ret as ISymbolValue;
                                        return(null);
                                    }
                                    else if (ret is AbstractType)
                                    {
                                        return new List <AbstractType> {
                                                   ret as AbstractType
                                        }
                                    }
                                    ;
                                }
                                else
                                {
                                    /*
                                     * If mr.Node is not a method, so e.g. if it's a variable
                                     * pointing to a delegate
                                     *
                                     * class Foo
                                     * {
                                     *	string opCall() {  return "asdf";  }
                                     * }
                                     *
                                     * Foo f=new Foo();
                                     * f(); -- calls opCall, opCall is not static
                                     */
                                    nextResults.Add(bt);
                                    requireStaticItems = false;
                                }
                                //TODO: Can other types work as function/are callable?
                            }
                        }
                    }
                    else if (b is DelegateType)
                    {
                        var ret = HandleCallDelegateType(ValueProvider, b as DelegateType, methodOverloads, returnBaseTypeOnly);
                        if (ret is ISymbolValue)
                        {
                            delegateValue = ret as ISymbolValue;
                            return(null);
                        }
                        else if (ret is AbstractType)
                        {
                            return new List <AbstractType> {
                                       ret as AbstractType
                            }
                        }
                        ;
                    }
                    else if (b is ClassType || b is StructType)
                    {
                        var tit = (TemplateIntermediateType)b;

                        /*
                         * auto a = MyStruct(); -- opCall-Overloads can be used
                         */
                        var classDef = tit.Definition;

                        if (classDef == null)
                        {
                            continue;
                        }

                        foreach (var i in ExpressionTypeEvaluation.GetOpCalls(tit, requireStaticItems))
                        {
                            methodOverloads.Add(TypeDeclarationResolver.HandleNodeMatch(i, ctxt, b, call) as MemberSymbol);
                        }

                        /*
                         * Every struct can contain a default ctor:
                         *
                         * struct S { int a; bool b; }
                         *
                         * auto s = S(1,true); -- ok
                         * auto s2= new S(2,false); -- error, no constructor found!
                         */
                        if (b is StructType && methodOverloads.Count == 0)
                        {
                            //TODO: Deduce parameters
                            return(new List <AbstractType> {
                                b
                            });
                        }
                    }

                    /*
                     * If the overload is a template, it quite exclusively means that we'll handle a method that is the only
                     * child inside a template + that is named as the template.
                     */
                    else if (b is TemplateType)
                    {
                        methodOverloads.Add(b);
                    }
                }

                scanResults = nextResults.Count == 0 ? null : nextResults.ToArray();
                nextResults.Clear();
            }
            #endregion

            if (methodOverloads.Count == 0)
            {
                return(null);
            }

            // Get all arguments' types
            callArguments = new List <ISemantic>();
            bool hasNonFinalArgs = false;

            if (call.Arguments != null)
            {
                if (ValueProvider != null)
                {
                    foreach (var arg in call.Arguments)
                    {
                        callArguments.Add(arg != null ? Evaluation.EvaluateValue(arg, ValueProvider) : null);
                    }
                }
                else
                {
                    foreach (var arg in call.Arguments)
                    {
                        callArguments.Add(arg != null ? ExpressionTypeEvaluation.EvaluateType(arg, ctxt) : null);
                    }
                }
            }

            #region If explicit template type args were given, try to associate them with each overload
            if (tix != null)
            {
                var args             = TemplateInstanceHandler.PreResolveTemplateArgs(tix, ctxt, out hasNonFinalArgs);
                var deducedOverloads = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(methodOverloads, args, true, ctxt, hasNonFinalArgs);
                methodOverloads.Clear();
                if (deducedOverloads != null)
                {
                    methodOverloads.AddRange(deducedOverloads);
                }
            }
            #endregion

            #region Filter by parameter-argument comparison
            var  argTypeFilteredOverloads   = new List <AbstractType>();
            bool hasHandledUfcsResultBefore = false;

            foreach (var ov in methodOverloads)
            {
                if (ov is MemberSymbol)
                {
                    HandleDMethodOverload(ctxt, ValueProvider != null, baseValue, callArguments, returnBaseTypeOnly, hasNonFinalArgs, argTypeFilteredOverloads, ref hasHandledUfcsResultBefore, ov as MemberSymbol);
                }
                else if (ov is DelegateType)
                {
                    var dg = ov as DelegateType;
                    var bt = dg.Base ?? TypeDeclarationResolver.GetMethodReturnType(dg, ctxt);

                    //TODO: Param-Arg check

                    if (returnBaseTypeOnly)
                    {
                        argTypeFilteredOverloads.Add(bt);
                    }
                    else
                    {
                        if (dg.Base == null)
                        {
                            if (dg.IsFunctionLiteral)
                            {
                                dg = new DelegateType(bt, dg.DeclarationOrExpressionBase as FunctionLiteral, dg.Parameters);
                            }
                            else
                            {
                                dg = new DelegateType(bt, dg.DeclarationOrExpressionBase as DelegateDeclaration, dg.Parameters);
                            }
                        }
                        argTypeFilteredOverloads.Add(new DelegateCallSymbol(dg, call));
                    }
                }
            }
            #endregion

            return(argTypeFilteredOverloads);
        }
Exemplo n.º 22
0
        /// <summary>
        /// Checks results for implicit type convertability
        /// </summary>
        public static bool IsImplicitlyConvertible(ISemantic resultToCheck, AbstractType targetType, ResolverContextStack ctxt = null)
        {
            var resToCheck = AbstractType.Get(resultToCheck);

            // Initially remove aliases from results
            var _r = DResolver.StripMemberSymbols(resToCheck);

            if (_r == null)
            {
                return(IsEqual(resToCheck, targetType));
            }
            resToCheck = _r;

            targetType = DResolver.StripAliasSymbol(targetType);

            if (targetType is DSymbol)
            {
                var tpn = ((DSymbol)targetType).Definition as TemplateParameterNode;

                if (tpn != null)
                {
                    var par = tpn.Parent as DNode;

                    if (par != null && par.TemplateParameters != null)
                    {
                        var dedParam = new DeducedTypeDictionary {
                            ParameterOwner = par
                        };
                        foreach (var tp in par.TemplateParameters)
                        {
                            dedParam[tp.Name] = null;
                        }

                        return(new TemplateParameterDeduction(dedParam, ctxt).Handle(tpn.TemplateParameter, resToCheck));
                    }
                }
            }

            _r = DResolver.StripMemberSymbols(targetType);
            if (_r == null)
            {
                return(false);
            }
            targetType = _r;

            if (resToCheck is PrimitiveType && targetType is PrimitiveType)
            {
                var sr1 = (PrimitiveType)resToCheck;
                var sr2 = (PrimitiveType)targetType;

                if (sr1.TypeToken == sr2.TypeToken && sr1.Modifier == sr2.Modifier)
                {
                    return(true);
                }

                switch (sr2.TypeToken)
                {
                case DTokens.Int:
                    return(sr1.TypeToken == DTokens.Uint);

                case DTokens.Uint:
                    return(sr1.TypeToken == DTokens.Int);
                    //TODO: Further types that can be converted into each other implicitly
                }
            }
            else if (resToCheck is UserDefinedType && targetType is UserDefinedType)
            {
                return(IsImplicitlyConvertible((UserDefinedType)resToCheck, (UserDefinedType)targetType));
            }
            else if (resToCheck is DelegateType && targetType is DelegateType)
            {
                //TODO
            }
            else if (resToCheck is ArrayType && targetType is ArrayType)
            {
                var ar1 = (ArrayType)resToCheck;
                var ar2 = (ArrayType)targetType;

                // Key as well as value types must be matching!
                var ar1_n = ar1.KeyType == null;
                var ar2_n = ar2.KeyType == null;

                if (ar1_n != ar2_n)
                {
                    return(false);
                }

                if (ar1_n || IsImplicitlyConvertible(ar1.KeyType, ar2.KeyType, ctxt))
                {
                    return(IsImplicitlyConvertible(ar1.Base, ar2.Base, ctxt));
                }
            }

            else if (resToCheck is TypeTuple && targetType is TypeTuple)
            {
                return(true);
            }
            else if (resToCheck is ExpressionTuple && targetType is ExpressionTuple)
            {
                return(true);
            }

            /*else if (resultToCheck is ExpressionValueResult && targetType is ExpressionValue)
             * {
             *      return ((ExpressionValueResult)resultToCheck).Value.Equals(((ExpressionValueResult)targetType).Value);
             * }*/

            // http://dlang.org/type.html
            //TODO: Pointer to non-pointer / vice-versa checkability? -- Can it really be done implicitly?

            return(false);
        }
Exemplo n.º 23
0
        /// <summary>
        /// Checks results for implicit type convertability
        /// </summary>
        public static bool IsImplicitlyConvertible(ISemantic resultToCheck, AbstractType targetType, ResolutionContext ctxt = null)
        {
            var  resToCheck = AbstractType.Get(resultToCheck);
            bool isVariable = resToCheck is MemberSymbol;

            // Initially remove aliases from results
            var _r = DResolver.StripMemberSymbols(resToCheck);

            if (_r == null)
            {
                return(IsEqual(resToCheck, targetType));
            }
            resToCheck = _r;

            targetType = DResolver.StripAliasSymbol(targetType);

            if (targetType is DSymbol)
            {
                var tpn = ((DSymbol)targetType).Definition as TemplateParameter.Node;

                if (tpn != null)
                {
                    var par = tpn.Parent as DNode;

                    if (par != null && par.TemplateParameters != null)
                    {
                        var dedParam = new DeducedTypeDictionary(par);

                        return(new TemplateParameterDeduction(dedParam, ctxt).Handle(tpn.TemplateParameter, resToCheck));
                    }
                }
            }

            _r = DResolver.StripMemberSymbols(targetType);
            if (_r == null)
            {
                return(false);
            }
            targetType = _r;

            if (resToCheck is PrimitiveType && targetType is PrimitiveType)
            {
                var sr1 = (PrimitiveType)resToCheck;
                var sr2 = (PrimitiveType)targetType;

                if (sr1.TypeToken == sr2.TypeToken /*&& sr1.Modifier == sr2.Modifier*/)
                {
                    return(true);
                }

                return(ImplicitConvertabilityTable.Contains((sr2.TypeToken << 8) + sr1.TypeToken));
            }
            else if (resToCheck is UserDefinedType && targetType is UserDefinedType)
            {
                return(IsImplicitlyConvertible((UserDefinedType)resToCheck, (UserDefinedType)targetType));
            }
            else if (resToCheck is DelegateType && targetType is DelegateType)
            {
                return(IsEqual(resToCheck, targetType));                //TODO: Can non-equal delegates be converted into each other?
            }
            else if (resToCheck is ArrayType && targetType is ArrayType)
            {
                var ar1 = (ArrayType)resToCheck;
                var ar2 = (ArrayType)targetType;

                // Key as well as value types must be matching!
                var ar1_n = ar1.KeyType == null;
                var ar2_n = ar2.KeyType == null;

                if (ar1_n != ar2_n)
                {
                    return(false);
                }

                if (ar1_n || IsImplicitlyConvertible(ar1.KeyType, ar2.KeyType, ctxt))
                {
                    return(IsImplicitlyConvertible(ar1.Base, ar2.Base, ctxt));
                }
            }
            else if (resToCheck is DSymbol && targetType is DSymbol)
            {
                var r1 = resToCheck as DSymbol;
                var r2 = targetType as DSymbol;

                if (r1.Definition == r2.Definition)
                {
                    //TODO: Compare template param deductions
                    return(true);
                }
            }
            else if (resToCheck is DTuple && targetType is DTuple)
            {
                var tup1 = resToCheck as DTuple;
                var tup2 = resToCheck as DTuple;

                //TODO
                return(true);
            }

            /*else if (resultToCheck is ExpressionValueResult && targetType is ExpressionValue)
             * {
             *      return ((ExpressionValueResult)resultToCheck).Value.Equals(((ExpressionValueResult)targetType).Value);
             * }*/

            // http://dlang.org/type.html
            //TODO: Pointer to non-pointer / vice-versa checkability? -- Can it really be done implicitly?
            else if (!isVariable &&
                     resToCheck is ArrayType &&
                     targetType is PointerType && ((targetType = (targetType as PointerType).Base) is PrimitiveType) &&
                     DTokens.IsBasicType_Character((targetType as PrimitiveType).TypeToken))
            {
                return((resultToCheck as ArrayType).IsString);
            }


            return(false);
        }
Exemplo n.º 24
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);
        }