Пример #1
0
        public static IExpression TryConvertTypeDeclaration(ITypeDeclaration td, bool ignoreInnerDeclaration = false)
        {
            if (td.InnerDeclaration == null || ignoreInnerDeclaration)
            {
                if (td is IdentifierDeclaration)
                {
                    var id = td as IdentifierDeclaration;
                    if (id.Id == null)
                        return null;
                    return new IdentifierExpression(id.Id) { Location = id.Location, EndLocation = id.EndLocation };
                }
                if (td is TemplateInstanceExpression)
                    return td as IExpression;

                return null;
            }

            var pfa = new PostfixExpression_Access{
                PostfixForeExpression = TryConvertTypeDeclaration(td.InnerDeclaration),
                AccessExpression  = TryConvertTypeDeclaration(td, true)
            };
            if (pfa.PostfixForeExpression == null)
                return null;
            return pfa;
        }
Пример #2
0
        List <IExpression> DoPrimaryIdCheck(PostfixExpression_Access acc)
        {
            var r = new List <IExpression>();

            while (acc != null)
            {
                if (DoPrimaryIdCheck(ExtractId(acc)))
                {
                    r.Add(acc);
                }

                // Scan down the access expression for other, deeper expressions
                if (acc.PostfixForeExpression is PostfixExpression_Access)
                {
                    acc = (PostfixExpression_Access)acc.PostfixForeExpression;
                }
                else
                {
                    if (DoPrimaryIdCheck(ExtractId(acc.PostfixForeExpression)))
                    {
                        r.Add(acc.PostfixForeExpression);
                    }
                    break;
                }
            }
            return(r);
        }
Пример #3
0
        public static IExpression TryConvertTypeDeclaration(ITypeDeclaration td, bool ignoreInnerDeclaration = false)
        {
            if (td.InnerDeclaration == null || ignoreInnerDeclaration)
            {
                if (td is IdentifierDeclaration)
                {
                    var id = td as IdentifierDeclaration;
                    if (id.Id == null)
                    {
                        return(null);
                    }
                    return(new IdentifierExpression(id.Id)
                    {
                        Location = id.Location, EndLocation = id.EndLocation
                    });
                }
                if (td is TemplateInstanceExpression)
                {
                    return(td as IExpression);
                }

                return(null);
            }

            var pfa = new PostfixExpression_Access {
                PostfixForeExpression = TryConvertTypeDeclaration(td.InnerDeclaration),
                AccessExpression      = TryConvertTypeDeclaration(td, true)
            };

            if (pfa.PostfixForeExpression == null)
            {
                return(null);
            }
            return(pfa);
        }
Пример #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);
        }
Пример #5
0
        public static List <AbstractType> TryResolveUFCS(
            ISemantic firstArgument,
            PostfixExpression_Access acc,
            ResolutionContext ctxt)
        {
            if (firstArgument == null || acc == null || ctxt == null)
            {
                return(new List <AbstractType>());
            }

            int name;

            if (acc.AccessExpression is IdentifierExpression)
            {
                name = ((IdentifierExpression)acc.AccessExpression).ValueStringHash;
            }
            else if (acc.AccessExpression is TemplateInstanceExpression)
            {
                name = ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash;
            }
            else
            {
                return(new List <AbstractType> ());
            }

            return(TryResolveUFCS(firstArgument, name, acc.PostfixForeExpression.Location, ctxt, acc));
        }
        public ISymbolValue Visit(PostfixExpression_Access ex)
        {
            var r = EvalPostfixAccessExpression(this, ctxt, ex, null, true, ValueProvider: ValueProvider);

            ctxt.CheckForSingleResult(r, ex);

            return(r != null && r.Length != 0 ? r[0] : null);
        }
Пример #7
0
        public AbstractType Visit(PostfixExpression_Access ex)
        {
            var r = Evaluation.EvalPostfixAccessExpression(this, ctxt, ex);

            ctxt.CheckForSingleResult(r, ex);

            return(r != null && r.Length != 0 ? r[0] : null);
        }
Пример #8
0
		public static MemberSymbol[] TryResolveUFCS(
			ISemantic firstArgument, 
			PostfixExpression_Access acc, 
			ResolutionContext ctxt)
		{
			if (ctxt == null)
				return null;
			
			int name=0;

			if (acc.AccessExpression is IdentifierExpression)
				name = ((IdentifierExpression)acc.AccessExpression).ValueStringHash;
			else if (acc.AccessExpression is TemplateInstanceExpression)
				name = ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash;
			else
				return null;

			var methodMatches = new List<MemberSymbol>();
			if(ctxt.ParseCache!=null)
				foreach (var pc in ctxt.ParseCache)
				{
					var tempResults=pc.UfcsCache.FindFitting(ctxt, acc.Location, firstArgument, name);

					if (tempResults != null)
						foreach (var m in tempResults)
						{
							ctxt.PushNewScope(m);

							if (m.TemplateParameters != null && m.TemplateParameters.Length != 0)
							{
								var ov = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(
									new[] { new MemberSymbol(m, null, acc) }, 
									new[] { firstArgument }, true, ctxt);

								if (ov == null || ov.Length == 0)
									continue;

								var ms = (DSymbol)ov[0];
								ctxt.CurrentContext.IntroduceTemplateParameterTypes(ms);
							}
							
							var mr = TypeDeclarationResolver.HandleNodeMatch(m, ctxt, null, acc) as MemberSymbol;
							if (mr!=null)
							{
								mr.FirstArgument = firstArgument;
								mr.DeducedTypes = ctxt.CurrentContext.DeducedTemplateParameters.ToReadonly();
								mr.IsUFCSResult = true;
								methodMatches.Add(mr);
							}
							ctxt.Pop();
						}
				}

			return methodMatches.Count == 0 ? null : methodMatches.ToArray();
		}
Пример #9
0
        public override void Visit(PostfixExpression_Access acc)
        {
            var resolvedSymbol = TryPopPFAStack();

            if ((acc.AccessExpression is IdentifierExpression &&
                 (acc.AccessExpression as IdentifierExpression).ValueStringHash != searchHash) ||
                (acc.AccessExpression is TemplateInstanceExpression &&
                 ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash))
            {
                acc.PostfixForeExpression.Accept(this);
                return;
            }
            else if (acc.AccessExpression is NewExpression)
            {
                var nex = acc.AccessExpression as NewExpression;

                if ((nex.Type is IdentifierDeclaration &&
                     ((IdentifierDeclaration)nex.Type).IdHash != searchHash) ||
                    (nex.Type is TemplateInstanceExpression &&
                     ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash))
                {
                    acc.PostfixForeExpression.Accept(this);
                    return;
                }
                // Are there other types to test for?
            }
            else
            {
                // 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))
            {
                acc.PostfixForeExpression.Accept(this);
                return;
            }

            // Scan down for other possible symbols
            if (s.Base is DSymbol)
            {
                postfixForeExprAccessStack.Push(s.Base as DSymbol);
            }
            acc.PostfixForeExpression.Accept(this);
        }
Пример #10
0
 public override void Visit(PostfixExpression_Access x)
 {
     if (x.AccessExpression != null &&
         x.AccessExpression.Location <= caret &&
         x.AccessExpression.EndLocation >= caret)
     {
         IdNearCaret = x;
     }
     else
     {
         base.Visit(x);
     }
 }
Пример #11
0
        public override void Visit(PostfixExpression_Access acc)
        {
            acc.PostfixForeExpression.Accept(this);

            if ((acc.AccessExpression is IdentifierExpression &&
                 (acc.AccessExpression as IdentifierExpression).ValueStringHash != searchHash) ||
                (acc.AccessExpression is TemplateInstanceExpression &&
                 ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash))
            {
                return;
            }
            else if (acc.AccessExpression is NewExpression)
            {
                var nex = acc.AccessExpression as NewExpression;

                if ((nex.Type is IdentifierDeclaration &&
                     ((IdentifierDeclaration)nex.Type).IdHash != searchHash) ||
                    (nex.Type is TemplateInstanceExpression &&
                     ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash))
                {
                    return;
                }
                // Are there other types to test for?
            }
            else
            {
                // Are there other types to test for?
            }

            ctxt.CurrentContext.Set(acc.Location);
            var ov = ExpressionTypeEvaluation.GetAccessedOverloads(acc, ctxt, null, false);

            if (ov == null)
            {
                return;
            }

            foreach (var o in ov)
            {
                if (TryAdd(o, acc.AccessExpression))
                {
                    return;
                }
            }
        }
Пример #12
0
        public static List<AbstractType> TryResolveUFCS(
			ISemantic firstArgument, 
			PostfixExpression_Access acc, 
			ResolutionContext ctxt)
        {
            if (firstArgument == null || acc == null || ctxt == null)
                return new List<AbstractType>();

            int name;

            if (acc.AccessExpression is IdentifierExpression)
                name = ((IdentifierExpression)acc.AccessExpression).ValueStringHash;
            else if (acc.AccessExpression is TemplateInstanceExpression)
                name = ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash;
            else
                return new List<AbstractType> ();

            return TryResolveUFCS (firstArgument, name, acc.PostfixForeExpression.Location, ctxt, acc);
        }
Пример #13
0
 public override void Visit(PostfixExpression_Access x)
 {
     if (IsIncompleteExpression(x.AccessExpression))
     {
         halt = true;
         if (x.PostfixForeExpression is TokenExpression && (x.PostfixForeExpression as TokenExpression).Token == DTokens.Dot)
         {
             // Handle module-scoped things:
             // When typing a dot without anything following, trigger completion and show types, methods and vars that are located in the module & import scope
             prv = new CtrlSpaceCompletionProvider(cdgen, scopedBlock, MemberFilter.Methods | MemberFilter.Types | MemberFilter.Variables | MemberFilter.TypeParameters);
         }
         else
         {
             prv = new MemberCompletionProvider(cdgen, x.PostfixForeExpression, scopedBlock);
         }
     }
     else
     {
         base.Visit(x);
     }
 }
Пример #14
0
        public static MemberSymbol[] TryResolveUFCS(
			ISemantic firstArgument, 
			PostfixExpression_Access acc, 
			ResolverContextStack ctxt)
        {
            if (ctxt == null)
                return null;

            var name="";

            if (acc.AccessExpression is IdentifierExpression)
                name = ((IdentifierExpression)acc.AccessExpression).Value as string;
            else if (acc.AccessExpression is TemplateInstanceExpression)
                name = ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdentifier.Id;
            else
                return null;

            var methodMatches = new List<MemberSymbol>();
            if(ctxt.ParseCache!=null)
                foreach (var pc in ctxt.ParseCache)
                {
                    var tempResults=pc.UfcsCache.FindFitting(ctxt, acc.Location, firstArgument, name);

                    if (tempResults != null)
                        foreach (var m in tempResults)
                        {
                            var mr = TypeDeclarationResolver.HandleNodeMatch(m, ctxt, TypeDeclarationResolver.Convert(firstArgument), acc) as MemberSymbol;

                            if (mr!=null)
                            {
                                mr.IsUFCSResult = true;
                                methodMatches.Add(mr);
                            }
                        }
                }

            return methodMatches.Count == 0 ? null : methodMatches.ToArray();
        }
Пример #15
0
        IExpression NonVoidInitializer(IBlockNode Scope = null)
        {
            TrackerVariables.IsParsingInitializer = true;

            #region ArrayInitializer
            if (laKind == OpenSquareBracket)
            {
                Step();

                // ArrayMemberInitializations
                var ae = new ArrayInitializer() { Location=t.Location};
                LastParsedObject = ae;
                var inits=new List<ArrayMemberInitializer>();

                bool IsInit = true;
                while (IsInit || laKind == (Comma))
                {
                    if (!IsInit) Step();
                    IsInit = false;

                    // Allow empty post-comma expression IF the following token finishes the initializer expression
                    // int[] a=[1,2,3,4,];
                    if (laKind == CloseSquareBracket)
                        break;

                    // ArrayMemberInitialization
                    var ami = new ArrayMemberInitializer()
                    {
                        Left = NonVoidInitializer(Scope)
                    };
                    LastParsedObject = ami;
                    bool HasBeenAssExpr = !(t.Kind == (CloseSquareBracket) || t.Kind == (CloseCurlyBrace));

                    // AssignExpression : NonVoidInitializer
                    if (HasBeenAssExpr && laKind == (Colon))
                    {
                        Step();
                        ami.Specialization = NonVoidInitializer(Scope);
                    }
                    inits.Add(ami);
                }

                ae.ArrayMemberInitializations = inits.ToArray();

                Expect(CloseSquareBracket);
                ae.EndLocation = t.EndLocation;

                // auto i=[1,2,3].idup; // in this case, this entire thing is meant to be an AssignExpression but not a dedicated initializer..
                if (laKind == Dot)
                {
                    Step();

                    var ae2 = new PostfixExpression_Access();
                    LastParsedObject = ae2;
                    ae2.PostfixForeExpression = ae;
                    ae2.TemplateOrIdentifier = Type(); //TODO: Is it really a type!?
                    ae2.EndLocation = t.EndLocation;

                    if (!IsEOF)
                        TrackerVariables.IsParsingInitializer = false;

                    return ae2;
                }

                if (!IsEOF)
                    TrackerVariables.IsParsingInitializer = false;

                return ae;
            }
            #endregion

            // StructInitializer
            if (laKind == OpenCurlyBrace)
            {
                // StructMemberInitializations
                var ae = new StructInitializer() { Location = la.Location };
                LastParsedObject = ae;
                var inits = new List<StructMemberInitializer>();

                bool IsInit = true;
                while (IsInit || laKind == (Comma))
                {
                    Step();
                    IsInit = false;

                    // Allow empty post-comma expression IF the following token finishes the initializer expression
                    // int[] a=[1,2,3,4,];
                    if (laKind == CloseCurlyBrace)
                        break;

                    // Identifier : NonVoidInitializer
                    var sinit = new StructMemberInitializer();
                    LastParsedObject = sinit;
                    if (laKind == Identifier && Lexer.CurrentPeekToken.Kind == Colon)
                    {
                        Step();
                        sinit.MemberName = t.Value;
                        Step();
                    }

                    sinit.Specialization = NonVoidInitializer(Scope);

                    inits.Add(sinit);
                }

                ae.StructMemberInitializers = inits.ToArray();

                Expect(CloseCurlyBrace);
                ae.EndLocation = t.EndLocation;

                if (!IsEOF)
                    TrackerVariables.IsParsingInitializer = false;

                return ae;
            }

            else
            {
                var expr= AssignExpression(Scope);

                if (!IsEOF)
                    TrackerVariables.IsParsingInitializer = false;

                return expr;
            }
        }
Пример #16
0
        IExpression PrimaryExpression(IBlockNode Scope=null)
        {
            bool isModuleScoped = false;
            // For minimizing possible overhead, skip 'useless' tokens like an initial dot <<< TODO
            if (isModuleScoped= laKind == Dot)
                Step();

            if (laKind == __FILE__ || laKind == __LINE__)
            {
                Step();

                object id = null;

                if (t.Kind == __FILE__ && doc != null)
                    id = doc.FileName;
                else if(t.Kind==__LINE__)
                    id = t.line;

                return new IdentifierExpression(id)
                {
                    Location=t.Location,
                    EndLocation=t.EndLocation
                };
            }

            // Dollar (== Array length expression)
            if (laKind == Dollar)
            {
                Step();
                return new TokenExpression(laKind)
                {
                    Location = t.Location,
                    EndLocation = t.EndLocation
                };
            }

            // TemplateInstance
            if (laKind == (Identifier) && Lexer.CurrentPeekToken.Kind == (Not)
                && (Peek().Kind != Is && Lexer.CurrentPeekToken.Kind != In)
                /* Very important: The 'template' could be a '!is'/'!in' expression - With two tokens each! */)
                return TemplateInstance();

            // Identifier
            if (laKind == (Identifier))
            {
                Step();
                return new IdentifierExpression(t.Value)
                {
                    Location = t.Location,
                    EndLocation = t.EndLocation
                };
            }

            // SpecialTokens (this,super,null,true,false,$) // $ has been handled before
            if (laKind == (This) || laKind == (Super) || laKind == (Null) || laKind == (True) || laKind == (False))
            {
                Step();
                return new TokenExpression(t.Kind)
                {
                    Location = t.Location,
                    EndLocation = t.EndLocation
                };
            }

            #region Literal
            if (laKind == Literal)
            {
                Step();
                var startLoc = t.Location;

                // Concatenate multiple string literals here
                if (t.LiteralFormat == LiteralFormat.StringLiteral || t.LiteralFormat == LiteralFormat.VerbatimStringLiteral)
                {
                    var a = t.LiteralValue as string;
                    while (la.LiteralFormat == LiteralFormat.StringLiteral || la.LiteralFormat == LiteralFormat.VerbatimStringLiteral)
                    {
                        Step();
                        a += t.LiteralValue as string;
                    }
                    return new IdentifierExpression(a, t.LiteralFormat) { Location = startLoc, EndLocation = t.EndLocation };
                }
                //else if (t.LiteralFormat == LiteralFormat.CharLiteral)return new IdentifierExpression(t.LiteralValue) { LiteralFormat=t.LiteralFormat,Location = startLoc, EndLocation = t.EndLocation };
                return new IdentifierExpression(t.LiteralValue, t.LiteralFormat) { Location = startLoc, EndLocation = t.EndLocation };
            }
            #endregion

            #region ArrayLiteral | AssocArrayLiteral
            if (laKind == (OpenSquareBracket))
            {
                Step();
                var startLoc = t.Location;

                // Empty array literal
                if (laKind == CloseSquareBracket)
                {
                    Step();
                    return new ArrayLiteralExpression() {Location=startLoc, EndLocation = t.EndLocation };
                }

                var firstExpression = AssignExpression();

                // Associtative array
                if (laKind == Colon)
                {
                    Step();

                    var ae = new AssocArrayExpression() { Location=startLoc};
                    LastParsedObject = ae;

                    var firstValueExpression = AssignExpression();

                    ae.KeyValuePairs.Add(firstExpression, firstValueExpression);

                    while (laKind == Comma)
                    {
                        Step();
                        var keyExpr = AssignExpression();
                        Expect(Colon);
                        var valueExpr = AssignExpression();

                        ae.KeyValuePairs.Add(keyExpr, valueExpr);
                    }

                    Expect(CloseSquareBracket);
                    ae.EndLocation = t.EndLocation;
                    return ae;
                }
                else // Normal array literal
                {
                    var ae = new ArrayLiteralExpression() { Location=startLoc};
                    LastParsedObject = ae;
                    var expressions = new List<IExpression>();
                    expressions.Add(firstExpression);

                    while (laKind == Comma)
                    {
                        Step();
                        if (laKind == CloseSquareBracket) // And again, empty expressions are allowed
                            break;
                        expressions.Add(AssignExpression());
                    }

                    ae.Expressions = expressions;

                    Expect(CloseSquareBracket);
                    ae.EndLocation = t.EndLocation;
                    return ae;
                }
            }
            #endregion

            #region FunctionLiteral
            if (laKind == Delegate || laKind == Function || laKind == OpenCurlyBrace || (laKind == OpenParenthesis && IsFunctionLiteral()))
            {
                var fl = new FunctionLiteral() { Location=la.Location};
                LastParsedObject = fl;
                fl.AnonymousMethod.StartLocation = la.Location;

                if (laKind == Delegate || laKind == Function)
                {
                    Step();
                    fl.LiteralToken = t.Kind;
                }

                // file.d:1248
                /*
                    listdir (".", delegate bool (DirEntry * de)
                    {
                        auto s = std.string.format("%s : c %s, w %s, a %s", de.name,
                                toUTCString (de.creationTime),
                                toUTCString (de.lastWriteTime),
                                toUTCString (de.lastAccessTime));
                        return true;
                    }
                    );
                */
                if (laKind != OpenCurlyBrace) // foo( 1, {bar();} ); -> is a legal delegate
                {
                    if (!MemberFunctionAttribute[laKind] && Lexer.CurrentPeekToken.Kind == OpenParenthesis)
                        fl.AnonymousMethod.Type = BasicType();
                    else if (laKind != OpenParenthesis && laKind != OpenCurlyBrace)
                        fl.AnonymousMethod.Type = Type();

                    if (laKind == OpenParenthesis)
                        fl.AnonymousMethod.Parameters = Parameters(fl.AnonymousMethod);
                }

                FunctionBody(fl.AnonymousMethod);

                fl.EndLocation = t.EndLocation;

                if (Scope != null)
                    Scope.Add(fl.AnonymousMethod);

                return fl;
            }
            #endregion

            #region AssertExpression
            if (laKind == (Assert))
            {
                Step();
                var startLoc = t.Location;
                Expect(OpenParenthesis);
                var ce = new AssertExpression() { Location=startLoc};
                LastParsedObject = ce;

                var exprs = new List<IExpression>();
                exprs.Add(AssignExpression());

                if (laKind == (Comma))
                {
                    Step();
                    exprs.Add(AssignExpression());
                }
                ce.AssignExpressions = exprs.ToArray();
                Expect(CloseParenthesis);
                ce.EndLocation = t.EndLocation;
                return ce;
            }
            #endregion

            #region MixinExpression | ImportExpression
            if (laKind == Mixin)
            {
                Step();
                var e = new MixinExpression() { Location=t.Location};
                LastParsedObject = e;
                Expect(OpenParenthesis);

                e.AssignExpression = AssignExpression();

                Expect(CloseParenthesis);
                e.EndLocation = t.EndLocation;
                return e;
            }

            if (laKind == Import)
            {
                Step();
                var e = new ImportExpression() { Location=t.Location};
                LastParsedObject = e;
                Expect(OpenParenthesis);

                e.AssignExpression = AssignExpression();

                Expect(CloseParenthesis);
                e.EndLocation = t.EndLocation;
                return e;
            }
            #endregion

            if (laKind == (Typeof))
            {
                var startLoc = la.Location;
                return new TypeDeclarationExpression(TypeOf()) {Location=startLoc,EndLocation=t.EndLocation};
            }

            // TypeidExpression
            if (laKind == (Typeid))
            {
                Step();
                var ce = new TypeidExpression() { Location=t.Location};
                LastParsedObject = ce;
                Expect(OpenParenthesis);

                AllowWeakTypeParsing = true;
                ce.Type = Type();
                AllowWeakTypeParsing = false;

                if (ce.Type==null)
                    ce.Expression = AssignExpression();

                Expect(CloseParenthesis);
                ce.EndLocation = t.EndLocation;
                return ce;
            }

            #region IsExpression
            if (laKind == Is)
            {
                Step();
                var ce = new IsExpression() { Location=t.Location};
                LastParsedObject = ce;
                Expect(OpenParenthesis);

                var LookAheadBackup = la;

                AllowWeakTypeParsing = true;
                ce.TestedType = Type();
                AllowWeakTypeParsing = false;

                if (ce.TestedType!=null && laKind == Identifier && (Lexer.CurrentPeekToken.Kind == CloseParenthesis || Lexer.CurrentPeekToken.Kind == Equal
                    || Lexer.CurrentPeekToken.Kind == Colon))
                {
                    Step();
                    ce.TypeAliasIdentifier = strVal;
                }
                else
                // D Language specs mistake: In an IsExpression there also can be expressions!
                if(ce.TestedType==null || !(laKind==CloseParenthesis || laKind==Equal||laKind==Colon))
                {
                    // Reset lookahead token to prior position
                    la = LookAheadBackup;
                    // Reset wrongly parsed type declaration
                    ce.TestedType = null;
                    ce.TestedExpression = ConditionalExpression();
                }

                if(ce.TestedExpression==null && ce.TestedType==null)
                    SynErr(laKind,"In an IsExpression, either a type or an expression is required!");

                if (laKind == CloseParenthesis)
                {
                    Step();
                    ce.EndLocation = t.EndLocation;
                    return ce;
                }

                if (laKind == Colon || laKind == Equal)
                {
                    Step();
                    ce.EqualityTest = t.Kind == Equal;
                }
                else if (laKind == CloseParenthesis)
                {
                    Step();
                    ce.EndLocation = t.EndLocation;
                    return ce;
                }

                /*
                TypeSpecialization:
                    Type
                        struct
                        union
                        class
                        interface
                        enum
                        function
                        delegate
                        super
                    const
                    immutable
                    inout
                    shared
                        return
                */

                if (ClassLike[laKind] || laKind==Typedef || // typedef is possible although it's not yet documented in the syntax docs
                    laKind==Enum || laKind==Delegate || laKind==Function || laKind==Super || laKind==Return)
                {
                    Step();
                    ce.TypeSpecializationToken = t.Kind;
                }
                else
                    ce.TypeSpecialization = Type();

                if (laKind == Comma)
                {
                    Step();
                    ce.TemplateParameterList =
                        TemplateParameterList(false);
                }

                Expect(CloseParenthesis);
                ce.EndLocation = t.EndLocation;
                return ce;
            }
            #endregion

            // ( Expression )
            if (laKind == OpenParenthesis)
            {
                Step();
                var ret = new SurroundingParenthesesExpression() {Location=t.Location };
                LastParsedObject = ret;

                ret.Expression = Expression();

                Expect(CloseParenthesis);
                ret.EndLocation = t.EndLocation;
                return ret;
            }

            // TraitsExpression
            if (laKind == (__traits))
                return TraitsExpression();

            #region BasicType . Identifier
            if (laKind == (Const) || laKind == (Immutable) || laKind == (Shared) || laKind == (InOut) || BasicTypes[laKind])
            {
                Step();
                var startLoc = t.Location;
                IExpression left = null;
                if (!BasicTypes[t.Kind])
                {
                    int tk = t.Kind;
                    // Put an artificial parenthesis around the following type declaration
                    if (laKind != OpenParenthesis)
                    {
                        var mttd = new MemberFunctionAttributeDecl(tk);
                        LastParsedObject = mttd;
                        mttd.InnerType = Type();
                        left = new TypeDeclarationExpression(mttd) { Location = startLoc, EndLocation = t.EndLocation };
                    }
                    else
                    {
                        Expect(OpenParenthesis);
                        var mttd = new MemberFunctionAttributeDecl(tk);
                        LastParsedObject = mttd;
                        mttd.InnerType = Type();
                        Expect(CloseParenthesis);
                        left = new TypeDeclarationExpression(mttd) { Location = startLoc, EndLocation = t.EndLocation };
                    }
                }
                else
                    left = new TokenExpression(t.Kind) {Location=startLoc,EndLocation=t.EndLocation };

                if (laKind == (Dot) && Peek(1).Kind==Identifier)
                {
                    Step();
                    Step();

                    var meaex = new PostfixExpression_Access() { PostfixForeExpression=left,
                        TemplateOrIdentifier=new IdentifierDeclaration(t.Value),EndLocation=t.EndLocation };

                    return meaex;
                }
                return left;
            }
            #endregion

            // TODO? Expressions can of course be empty...
            //return null;

            SynErr(Identifier);
            Step();
            return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation };
        }
		public void Visit(PostfixExpression_Access x)
		{
			
		}
Пример #18
0
        IExpression PostfixExpression(IBlockNode Scope = null)
        {
            IExpression leftExpr = null;

            /*
             * Despite the following syntax is an explicit UnaryExpression (see http://dlang.org/expression.html#UnaryExpression),
             * stuff like (MyType).init[] is actually allowed - so it's obviously a PostfixExpression! (Nov 13 2013)
             */

            // ( Type ) . Identifier
            if (laKind == OpenParenthesis)
            {
                Lexer.StartPeek();
                OverPeekBrackets(OpenParenthesis, false);
                var dotToken = Lexer.CurrentPeekToken;

                if (Lexer.CurrentPeekToken.Kind == DTokens.Dot &&
                    (Peek().Kind == DTokens.Identifier || Lexer.CurrentPeekToken.Kind == EOF))
                {
                    var wkParsing = AllowWeakTypeParsing;
                    AllowWeakTypeParsing = true;
                    Lexer.PushLookAheadBackup();
                    Step();
                    var startLoc = t.Location;

                    var td = Type();

                    AllowWeakTypeParsing = wkParsing;

                    /*
                     * (a. -- expression: (a.myProp + 2) / b;
                     * (int. -- must be expression anyway
                     * (const).asdf -- definitely unary expression ("type")
                     * (const). -- also treat it as type accessor
                     */
                    if (td != null &&
                        laKind == CloseParenthesis && Lexer.CurrentPeekToken == dotToken) // Also take it as a type declaration if there's nothing following (see Expression Resolving)
                    {
                        Step();  // Skip to )
                        if (laKind == DTokens.Dot)
                        {
                            Step();  // Skip to .
                            if ((laKind == DTokens.Identifier && Peek(1).Kind != Not && Peek(1).Kind != OpenParenthesis) || IsEOF)
                            {
                                Lexer.PopLookAheadBackup();
                                Step();  // Skip to identifier

                                leftExpr = new UnaryExpression_Type()
                                {
                                    Type = td,
                                    AccessIdentifier = t.Value,
                                    Location = startLoc,
                                    EndLocation = t.EndLocation
                                };
                            }
                            else
                                Lexer.RestoreLookAheadBackup();
                        }
                        else
                            Lexer.RestoreLookAheadBackup();
                    }
                    else
                        Lexer.RestoreLookAheadBackup();
                }
            }

            // PostfixExpression
            if(leftExpr == null)
                leftExpr = PrimaryExpression(Scope);

            while (!IsEOF)
            {
                switch (laKind)
                {
                    case Dot:
                        Step();

                        var pea = new PostfixExpression_Access {
                            PostfixForeExpression = leftExpr
                        };

                        leftExpr = pea;

                        if (laKind == New)
                            pea.AccessExpression = PostfixExpression(Scope);
                        else if (IsTemplateInstance)
                            pea.AccessExpression = TemplateInstance(Scope);
                        else if (Expect(Identifier))
                            pea.AccessExpression = new IdentifierExpression(t.Value) {
                                Location = t.Location,
                                EndLocation = t.EndLocation
                            };
                        else if (IsEOF)
                            pea.AccessExpression = new TokenExpression(DTokens.Incomplete);

                        pea.EndLocation = t.EndLocation;
                        break;
                    case Increment:
                    case Decrement:
                        Step();
                        var peid = t.Kind == Increment ? (PostfixExpression)new PostfixExpression_Increment() : new PostfixExpression_Decrement();
                        peid.EndLocation = t.EndLocation;
                        peid.PostfixForeExpression = leftExpr;
                        leftExpr = peid;
                        break;
                    // Function call
                    case OpenParenthesis:
                        Step();
                        var pemc = new PostfixExpression_MethodCall();
                        pemc.PostfixForeExpression = leftExpr;
                        leftExpr = pemc;

                        if (laKind == CloseParenthesis)
                            Step();
                        else
                        {
                            pemc.Arguments = ArgumentList(Scope).ToArray();
                            Expect(CloseParenthesis);
                        }

                        if(IsEOF)
                            pemc.EndLocation = CodeLocation.Empty;
                        else
                            pemc.EndLocation = t.EndLocation;
                        break;
                    // IndexExpression | SliceExpression
                    case OpenSquareBracket:
                        Step();

                        if (laKind != CloseSquareBracket)
                        {
                            var firstEx = AssignExpression(Scope);
                            // [ AssignExpression .. AssignExpression ]
                            if (laKind == DoubleDot)
                            {
                                Step();

                                leftExpr = new PostfixExpression_Slice()
                                {
                                    FromExpression = firstEx,
                                    PostfixForeExpression = leftExpr,
                                    ToExpression = AssignExpression(Scope)
                                };
                            }
                            // [ ArgumentList ]
                            else if (laKind == CloseSquareBracket || laKind == (Comma))
                            {
                                var args = new List<IExpression>();
                                args.Add(firstEx);
                                if (laKind == Comma)
                                {
                                    Step();
                                    args.AddRange(ArgumentList(Scope));
                                }

                                leftExpr = new PostfixExpression_Index()
                                {
                                    PostfixForeExpression = leftExpr,
                                    Arguments = args.ToArray()
                                };
                            }
                        }
                        else // Empty array literal = SliceExpression
                        {
                            leftExpr = new PostfixExpression_Slice()
                            {
                                PostfixForeExpression=leftExpr
                            };
                        }

                        Expect(CloseSquareBracket);
                        if(leftExpr is PostfixExpression)
                            ((PostfixExpression)leftExpr).EndLocation = t.EndLocation;
                        break;
                    default:
                        return leftExpr;
                }
            }

            return leftExpr;
        }
Пример #19
0
        IExpression ParseAsmPrimaryExpression(IBlockNode Scope, IStatement Parent)
        {
            switch (laKind)
            {
                case OpenSquareBracket:
                    Step();
                    var e = new PostfixExpression_Index() { EndLocation = t.EndLocation };
                    e.Arguments = new IExpression[] { ParseAsmExpression(Scope, Parent) };
                    Expect(CloseSquareBracket);
                    return e;
                case Dollar:
                    var ins = Parent as AsmStatement.InstructionStatement;
                    if (ins == null || (!ins.IsJmpFamily && ins.Operation != AsmStatement.InstructionStatement.OpCode.call))
                        SynErr(Dollar, "The $ operator is only valid on jmp and call instructions!");
                    Step();
                    return new TokenExpression(t.Kind) { Location = t.Location, EndLocation = t.EndLocation };
                case Literal:
                    Step();
                    return new IdentifierExpression(t.LiteralValue, t.LiteralFormat, t.Subformat) { Location = t.Location, EndLocation = t.EndLocation };

                // AsmTypePrefix
                case DTokens.Byte:
                case DTokens.Short:
                case DTokens.Int:
                case DTokens.Float:
                case DTokens.Double:
                case DTokens.Real:

                case __LOCAL_SIZE:
                    Step ();
                    return new TokenExpression(t.Kind)  { Location = t.Location, EndLocation = t.EndLocation };
                case Identifier:
                    Step();
                    if (AsmRegisterExpression.IsRegister(t.Value))
                    {
                        string reg = t.Value;
                        if (reg == "ST" && laKind == OpenParenthesis)
                        {
                            reg += "(";
                            Step();
                            Expect(Literal);
                            reg += t.LiteralValue.ToString();
                            if (laKind != CloseParenthesis)
                                SynErr(CloseParenthesis);
                            else
                                Step();
                            reg += ")";
                        }
                        switch (reg)
                        {
                            case "ES":
                            case "CS":
                            case "SS":
                            case "DS":
                            case "GS":
                            case "FS":
                                if (laKind == Colon)
                                {
                                    var ex = new AsmRegisterExpression() { Location = t.Location, EndLocation = t.EndLocation, Register = string.Intern(reg) };
                                    Step();
                                    // NOTE: DMD actually allows you to not have an expression after a
                                    //       segment specifier, however I consider this a bug, and, as
                                    //       such, am making an expression in that form fail to parse.
                                    return new UnaryExpression_SegmentBase() { RegisterExpression = ex, UnaryExpression = ParseAsmExpression(Scope, Parent) };
                                }
                                break;
                        }
                        return new AsmRegisterExpression() { Location = t.Location, EndLocation = t.EndLocation, Register = string.Intern(reg) };
                    }
                    else
                    {
                        IExpression outer = new IdentifierExpression(t.Value) { Location = t.Location, EndLocation = t.EndLocation };
                        while (laKind == Dot)
                        {
                            Step();
                            if (laKind != Identifier)
                                SynErr(Identifier);
                            outer = new PostfixExpression_Access() { AccessExpression = new IdentifierExpression(la.Value), PostfixForeExpression = outer };
                            Step();
                        }
                        return outer;
                    }
                default:
                    SynErr(Identifier, "Expected a $, literal or an identifier!");
                    Step();
                    if (IsEOF)
                        return new TokenExpression(Incomplete);
                    return null;
            }
        }
        /// <summary>
        /// Returns either all unfiltered and undeduced overloads of a member of a base type/value (like b from type a if the expression is a.b).
        /// if <param name="EvalAndFilterOverloads"></param> is false.
        /// If true, all overloads will be deduced, filtered and evaluated, so that (in most cases,) a one-item large array gets returned
        /// which stores the return value of the property function b that is executed without arguments.
        /// Also handles UFCS - so if filtering is wanted, the function becom
        /// </summary>
        ISemantic[] E(PostfixExpression_Access acc,
			ISemantic resultBase = null, bool EvalAndFilterOverloads = true, bool ResolveImmediateBaseType = true)
        {
            if (acc == null)
                return null;

            var baseExpression = resultBase ?? E(acc.PostfixForeExpression);

            if (acc.AccessExpression is NewExpression)
            {
                /*
                 * This can be both a normal new-Expression as well as an anonymous class declaration!
                 */
                //TODO!
                return null;
            }

            AbstractType[] overloads;
            var optBackup = ctxt.CurrentContext.ContextDependentOptions;

            if (acc.AccessExpression is TemplateInstanceExpression)
            {
                if (!ResolveImmediateBaseType)
                    ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;

                var tix = (TemplateInstanceExpression)acc.AccessExpression;
                // Do not deduce and filter if superior expression is a method call since call arguments' types also count as template arguments!
                overloads = GetOverloads(tix, new[] { AbstractType.Get(baseExpression) }, EvalAndFilterOverloads);

                if (!ResolveImmediateBaseType)
                    ctxt.CurrentContext.ContextDependentOptions = optBackup;
            }

            else if (acc.AccessExpression is IdentifierExpression)
            {
                var id = acc.AccessExpression as IdentifierExpression;

                if (eval && EvalAndFilterOverloads && resultBase != null)
                {
                    var staticPropResult = StaticProperties.TryEvalPropertyValue(ValueProvider, resultBase, id.ValueStringHash);
                    if (staticPropResult != null)
                        return new[]{staticPropResult};
                }

                if (!ResolveImmediateBaseType)
                    ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;

                overloads = GetOverloads(id, new[] { AbstractType.Get(baseExpression) }, EvalAndFilterOverloads);

                if (!ResolveImmediateBaseType)
                    ctxt.CurrentContext.ContextDependentOptions = optBackup;
            }
            else
            {
                if (eval){
                    EvalError(acc, "Invalid access expression");
                    return null;
                }
                ctxt.LogError(acc, "Invalid post-dot expression");
                return null;
            }

            /*
             * Try to get ufcs functions at first!
             *
             * void foo(int i) {}
             *
             * class A
             * {
             *	void foo(int i, int a) {}
             *
             *	void bar(){
             *		123.foo(23); // Not allowed!
             *		// Anyway, if we tried to search ufcs functions AFTER searching from child to parent scope levels,
             *		// it would return the local foo() only, not the global one..which would be an error then!
             *  }
             *
             * Probably also worth to notice is the property syntax..are property functions rather preferred than ufcs ones?
             * }
             */
            if(overloads == null || EvalAndFilterOverloads)
            {
                var	oo = UFCSResolver.TryResolveUFCS(baseExpression, acc, ctxt) as AbstractType[];

                if(oo != null)
                {
                    int overloadsLength = overloads == null ? 0 : overloads.Length;
                    var newArr = new AbstractType[overloadsLength + oo.Length];
                    if(overloadsLength != 0)
                        overloads.CopyTo(newArr,0);
                    oo.CopyTo(newArr, overloadsLength);
                    overloads = newArr;
                }
            }

            // If evaluation active and the access expression is stand-alone, return a single item only.
            if (EvalAndFilterOverloads && eval)
                return new[] { TryDoCTFEOrGetValueRefs(overloads, acc.AccessExpression) };

            return overloads;
        }
Пример #21
0
 public AbstractType Visit(PostfixExpression_Access ex)
 {
     return(TryPretendMethodExecution(AmbiguousType.Get(Evaluation.EvalPostfixAccessExpression(this, ctxt, ex))));
 }
Пример #22
0
 public static AbstractType[] GetAccessedOverloads(PostfixExpression_Access acc, ResolutionContext ctxt,
                                                   ISemantic resultBase = null, bool DeducePostfixTemplateParams = true)
 {
     return(TypeDeclarationResolver.Convert(new Evaluation(ctxt).E(acc, resultBase, DeducePostfixTemplateParams)));
 }
		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;
		}
        /// <summary>
        /// Returns either all unfiltered and undeduced overloads of a member of a base type/value (like b from type a if the expression is a.b).
        /// if <param name="EvalAndFilterOverloads"></param> is false.
        /// If true, all overloads will be deduced, filtered and evaluated, so that (in most cases,) a one-item large array gets returned
        /// which stores the return value of the property function b that is executed without arguments.
        /// Also handles UFCS - so if filtering is wanted, the function becom
        /// </summary>
        ISemantic[] E(PostfixExpression_Access acc, out bool IsUFCS,
			ISemantic resultBase = null, bool EvalAndFilterOverloads = true)
        {
            IsUFCS = false;

            if (acc == null)
                return null;

            var baseExpression = resultBase ?? E(acc.PostfixForeExpression);

            if (acc.AccessExpression is NewExpression)
            {
                /*
                 * This can be both a normal new-Expression as well as an anonymous class declaration!
                 */
                //TODO!
                return null;
            }

            /*
             * Try to get ufcs functions at first!
             *
             * void foo(int i) {}
             *
             * class A
             * {
             *	void foo(int i, int a) {}
             *
             *	void bar(){
             *		123.foo(23); // Not allowed!
             *		// Anyway, if we tried to search ufcs functions AFTER searching from child to parent scope levels,
             *		// it would return the local foo() only, not the global one..which would be an error then!
             *  }
             *
             * Probably also worth to notice is the property syntax..are property functions rather preferred than ufcs ones?
             * }
             */
            var	overloads = UFCSResolver.TryResolveUFCS(baseExpression, acc, ctxt) as AbstractType[];

            if (overloads == null)
            {
                if (acc.AccessExpression is TemplateInstanceExpression)
                {
                    var tix = (TemplateInstanceExpression)acc.AccessExpression;
                    // Do not deduce and filter if superior expression is a method call since call arguments' types also count as template arguments!
                    overloads = GetOverloads(tix, resultBase == null ? null : new[] { AbstractType.Get(resultBase) }, EvalAndFilterOverloads);
                }

                else if (acc.AccessExpression is IdentifierExpression)
                {
                    var id = ((IdentifierExpression)acc.AccessExpression).Value as string;

                    overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(id, new[] { AbstractType.Get(baseExpression) }, ctxt, acc.AccessExpression);

                    // Might be a static property
                    if (overloads == null)
                    {
                        var staticTypeProperty = StaticPropertyResolver.TryResolveStaticProperties(AbstractType.Get(baseExpression), id, ctxt);

                        if (staticTypeProperty != null)
                            return new[] { staticTypeProperty };
                    }
                }
                else
                {
                    if (eval)
                        throw new EvaluationException(acc, "Invalid access expression");
                    ctxt.LogError(acc, "Invalid post-dot expression");
                    return null;
                }
            }
            else
                IsUFCS = true;

            // If evaluation active and the access expression is stand-alone, return a single item only.
            if (EvalAndFilterOverloads && eval)
                return new[] { TryDoCTFEOrGetValueRefs(overloads, acc.AccessExpression) };

            return overloads;
        }
Пример #25
0
 public override void Visit(PostfixExpression_Access x)
 {
     // q.AddRange(DoPrimaryIdCheck(x));
     base.Visit(x);
 }
Пример #26
0
 public override void Visit(PostfixExpression_Access x)
 {
     // q.AddRange(DoPrimaryIdCheck(x));
     base.Visit (x);
 }
Пример #27
0
        IExpression PostfixExpression(IBlockNode Scope = null)
        {
            var curLastParsedObj = LastParsedObject;

            // PostfixExpression
            IExpression leftExpr = PrimaryExpression(Scope);

            if(curLastParsedObj==LastParsedObject)
                LastParsedObject = leftExpr;

            while (!IsEOF)
            {
                if (laKind == Dot)
                {
                    Step();

                    var e = new PostfixExpression_Access {
                        PostfixForeExpression=leftExpr
                    };
                    LastParsedObject = e;

                    leftExpr = e;

                    if (laKind == New)
                        e.AccessExpression = NewExpression(Scope);
                    else if (IsTemplateInstance)
                        e.AccessExpression = TemplateInstance();
                    else if (Expect(Identifier))
                        e.AccessExpression = new IdentifierExpression(t.Value) { Location=t.Location, EndLocation=t.EndLocation };

                    e.EndLocation = t.EndLocation;
                }
                else if (laKind == Increment || laKind == Decrement)
                {
                    Step();
                    var e = t.Kind == Increment ? (PostfixExpression)new PostfixExpression_Increment() : new PostfixExpression_Decrement();
                    LastParsedObject = e;
                    e.EndLocation = t.EndLocation;
                    e.PostfixForeExpression = leftExpr;
                    leftExpr = e;
                }

                // Function call
                else if (laKind == OpenParenthesis)
                {
                    Step();
                    var ae = new PostfixExpression_MethodCall();
                    LastParsedObject = ae;
                    ae.PostfixForeExpression = leftExpr;
                    leftExpr = ae;

                    if (laKind != CloseParenthesis)
                        ae.Arguments = ArgumentList(Scope).ToArray();
                    Step();
                    ae.EndLocation = t.EndLocation;
                }

                // IndexExpression | SliceExpression
                else if (laKind == OpenSquareBracket)
                {
                    Step();

                    if (laKind != CloseSquareBracket)
                    {
                        var firstEx = AssignExpression(Scope);
                        // [ AssignExpression .. AssignExpression ]
                        if (laKind == DoubleDot)
                        {
                            Step();

                            leftExpr = new PostfixExpression_Slice()
                            {
                                FromExpression = firstEx,
                                PostfixForeExpression = leftExpr,
                                ToExpression = AssignExpression(Scope)
                            };
                            LastParsedObject = leftExpr;
                        }
                        // [ ArgumentList ]
                        else if (laKind == CloseSquareBracket || laKind == (Comma))
                        {
                            var args = new List<IExpression>();
                            args.Add(firstEx);
                            if (laKind == Comma)
                            {
                                Step();
                                args.AddRange(ArgumentList(Scope));
                            }

                            leftExpr = new PostfixExpression_Index()
                            {
                                PostfixForeExpression = leftExpr,
                                Arguments = args.ToArray()
                            };
                            LastParsedObject = leftExpr;
                        }
                    }
                    else // Empty array literal = SliceExpression
                    {
                        leftExpr = new PostfixExpression_Slice()
                        {
                            PostfixForeExpression=leftExpr
                        };
                        LastParsedObject = leftExpr;
                    }

                    Expect(CloseSquareBracket);
                    if(leftExpr is PostfixExpression)
                        ((PostfixExpression)leftExpr).EndLocation = t.EndLocation;
                }
                else break;
            }

            return leftExpr;
        }
Пример #28
0
		public override void Visit (PostfixExpression_Access acc)
		{
			acc.PostfixForeExpression.Accept(this);

			var id = acc.AccessExpression is NewExpression ? (acc.AccessExpression as NewExpression).Type as IntermediateIdType : acc.AccessExpression as IntermediateIdType;
			//TODO: Other types? Have additional facilities to extract an ID out of some expression?
			if (id != null && id.IdHash != searchHash)
				return;

			ctxt.CurrentContext.Set (acc.Location);
			var ov = ExpressionTypeEvaluation.GetAccessedOverloads (acc, ctxt, null, false);
			if (ov == null)
				return;

			foreach (var o in ov)
				if (TryAdd (o, acc.AccessExpression))
					return;
		}
Пример #29
0
        /// <summary>
        /// Returns either all unfiltered and undeduced overloads of a member of a base type/value (like b from type a if the expression is a.b).
        /// if <param name="EvalAndFilterOverloads"></param> is false.
        /// If true, all overloads will be deduced, filtered and evaluated, so that (in most cases,) a one-item large array gets returned
        /// which stores the return value of the property function b that is executed without arguments.
        /// Also handles UFCS - so if filtering is wanted, the function becom
        /// </summary>
        ISemantic[] E(PostfixExpression_Access acc,
                      ISemantic resultBase = null, bool EvalAndFilterOverloads = true, bool ResolveImmediateBaseType = true)
        {
            if (acc == null)
            {
                return(null);
            }

            var baseExpression = resultBase ?? E(acc.PostfixForeExpression);

            if (acc.AccessExpression is NewExpression)
            {
                /*
                 * This can be both a normal new-Expression as well as an anonymous class declaration!
                 */
                //TODO!
                return(null);
            }


            AbstractType[] overloads;
            var            optBackup = ctxt.CurrentContext.ContextDependentOptions;

            if (acc.AccessExpression is TemplateInstanceExpression)
            {
                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;
                }

                var tix = (TemplateInstanceExpression)acc.AccessExpression;
                // Do not deduce and filter if superior expression is a method call since call arguments' types also count as template arguments!
                overloads = GetOverloads(tix, new[] { AbstractType.Get(baseExpression) }, EvalAndFilterOverloads);

                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions = optBackup;
                }
            }

            else if (acc.AccessExpression is IdentifierExpression)
            {
                var id = acc.AccessExpression as IdentifierExpression;

                if (eval && EvalAndFilterOverloads && resultBase != null)
                {
                    var staticPropResult = StaticProperties.TryEvalPropertyValue(ValueProvider, resultBase, id.ValueStringHash);
                    if (staticPropResult != null)
                    {
                        return new[] { staticPropResult }
                    }
                    ;
                }

                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;
                }

                overloads = TypeDeclarationResolver.ResolveFurtherTypeIdentifier(id.ValueStringHash, new[] { AbstractType.Get(baseExpression) }, ctxt, acc.AccessExpression);

                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions = optBackup;
                }
            }
            else
            {
                if (eval)
                {
                    EvalError(acc, "Invalid access expression");
                    return(null);
                }
                ctxt.LogError(acc, "Invalid post-dot expression");
                return(null);
            }

            /*
             * Try to get ufcs functions at first!
             *
             * void foo(int i) {}
             *
             * class A
             * {
             *	void foo(int i, int a) {}
             *
             *	void bar(){
             *		123.foo(23); // Not allowed!
             *		// Anyway, if we tried to search ufcs functions AFTER searching from child to parent scope levels,
             *		// it would return the local foo() only, not the global one..which would be an error then!
             *  }
             *
             * Probably also worth to notice is the property syntax..are property functions rather preferred than ufcs ones?
             * }
             */
            if (overloads == null || EvalAndFilterOverloads)
            {
                var oo = UFCSResolver.TryResolveUFCS(baseExpression, acc, ctxt) as AbstractType[];

                if (oo != null)
                {
                    int overloadsLength = overloads == null ? 0 : overloads.Length;
                    var newArr          = new AbstractType[overloadsLength + oo.Length];
                    if (overloadsLength != 0)
                    {
                        overloads.CopyTo(newArr, 0);
                    }
                    oo.CopyTo(newArr, overloadsLength);
                    overloads = newArr;
                }
            }

            // If evaluation active and the access expression is stand-alone, return a single item only.
            if (EvalAndFilterOverloads && eval)
            {
                return new[] { TryDoCTFEOrGetValueRefs(overloads, acc.AccessExpression) }
            }
            ;

            return(overloads);
        }

        ISemantic E(PostfixExpression_Index x, ISemantic foreExpression)
        {
            if (eval)
            {
                //TODO: Access pointer arrays(?)

                if (foreExpression is ArrayValue)                 // ArrayValue must be checked first due to inheritance!
                {
                    var av = foreExpression as ArrayValue;

                    // Make $ operand available
                    var arrLen_Backup = ValueProvider.CurrentArrayLength;
                    ValueProvider.CurrentArrayLength = av.Elements.Length;

                    var n = E(x.Arguments[0]) as PrimitiveValue;

                    ValueProvider.CurrentArrayLength = arrLen_Backup;

                    if (n == null)
                    {
                        EvalError(x.Arguments[0], "Returned no value");
                        return(null);
                    }

                    int i = 0;
                    try{
                        i = Convert.ToInt32(n.Value);
                    }
                    catch
                    {
                        EvalError(x.Arguments[0], "Index expression must be of type int");
                        return(null);
                    }

                    if (i < 0 || i > av.Elements.Length)
                    {
                        EvalError(x.Arguments[0], "Index out of range - it must be between 0 and " + av.Elements.Length);
                        return(null);
                    }

                    return(av.Elements[i]);
                }
                else if (foreExpression is AssociativeArrayValue)
                {
                    var aa = (AssociativeArrayValue)foreExpression;

                    var key = E(x.Arguments[0]);

                    if (key == null)
                    {
                        EvalError(x.Arguments[0], "Returned no value");
                        return(null);
                    }

                    ISymbolValue val = null;

                    foreach (var kv in aa.Elements)
                    {
                        if (kv.Key.Equals(key))
                        {
                            return(kv.Value);
                        }
                    }

                    EvalError(x, "Could not find key '" + val + "'");
                    return(null);
                }

                EvalError(x.PostfixForeExpression, "Invalid index expression base value type", foreExpression);

                return(null);
            }
            else
            {
                foreExpression = DResolver.StripMemberSymbols(AbstractType.Get(foreExpression));

                if (foreExpression is AssocArrayType)
                {
                    var ar = foreExpression as AssocArrayType;

                    /*
                     * myType_Array[0] -- returns TypeResult myType
                     * return the value type of a given array result
                     */
                    //TODO: Handle opIndex overloads

                    return(new ArrayAccessSymbol(x, ar.ValueType));
                }

                /*
                 * int* a = new int[10];
                 *
                 * a[0] = 12;
                 */
                else if (foreExpression is PointerType)
                {
                    return((foreExpression as PointerType).Base);
                }
                //return new ArrayAccessSymbol(x,((PointerType)foreExpression).Base);

                else if (foreExpression is DTuple)
                {
                    var tt = foreExpression as DTuple;

                    if (x.Arguments != null && x.Arguments.Length != 0)
                    {
                        var idx = EvaluateValue(x.Arguments[0], ctxt) as PrimitiveValue;

                        if (idx == null || !DTokens.BasicTypes_Integral[idx.BaseTypeToken])
                        {
                            ctxt.LogError(x.Arguments[0], "Index expression must evaluate to integer value");
                        }
                        else if (idx.Value > (decimal)Int32.MaxValue ||
                                 (int)idx.Value >= tt.Items.Length ||
                                 (int)idx.Value < 0)
                        {
                            ctxt.LogError(x.Arguments[0], "Index number must be a value between 0 and " + tt.Items.Length);
                        }
                        else
                        {
                            return(tt.Items[(int)idx.Value]);
                        }
                    }
                }

                ctxt.LogError(new ResolutionError(x, "Invalid base type for index expression"));
            }

            return(null);
        }

        ISemantic E(PostfixExpression_Slice x, ISemantic foreExpression)
        {
            if (!eval)
            {
                return(foreExpression);                // Still of the array's type.
            }
            if (!(foreExpression is ArrayValue))
            {
                EvalError(x.PostfixForeExpression, "Must be an array");
                return(null);
            }

            var ar = (ArrayValue)foreExpression;
            var sl = (PostfixExpression_Slice)x;

            // If the [ ] form is used, the slice is of the entire array.
            if (sl.FromExpression == null && sl.ToExpression == null)
            {
                return(foreExpression);
            }

            // Make $ operand available
            var arrLen_Backup = ValueProvider.CurrentArrayLength;

            ValueProvider.CurrentArrayLength = ar.Elements.Length;

            var bound_lower = E(sl.FromExpression) as PrimitiveValue;
            var bound_upper = E(sl.ToExpression) as PrimitiveValue;

            ValueProvider.CurrentArrayLength = arrLen_Backup;

            if (bound_lower == null || bound_upper == null)
            {
                EvalError(bound_lower == null ? sl.FromExpression : sl.ToExpression, "Must be of an integral type");
                return(null);
            }

            int lower = -1, upper = -1;

            try
            {
                lower = Convert.ToInt32(bound_lower.Value);
                upper = Convert.ToInt32(bound_upper.Value);
            }
            catch { EvalError(lower != -1 ? sl.FromExpression : sl.ToExpression, "Boundary expression must base an integral type");
                    return(null); }

            if (lower < 0)
            {
                EvalError(sl.FromExpression, "Lower boundary must be greater than 0"); return(null);
            }
            if (lower >= ar.Elements.Length)
            {
                EvalError(sl.FromExpression, "Lower boundary must be smaller than " + ar.Elements.Length); return(null);
            }
            if (upper < lower)
            {
                EvalError(sl.ToExpression, "Upper boundary must be greater than " + lower); return(null);
            }
            if (upper >= ar.Elements.Length)
            {
                EvalError(sl.ToExpression, "Upper boundary must be smaller than " + ar.Elements.Length); return(null);
            }


            var rawArraySlice = new ISymbolValue[upper - lower];
            int j             = 0;

            for (int i = lower; i < upper; i++)
            {
                rawArraySlice[j++] = ar.Elements[i];
            }

            return(new ArrayValue(ar.RepresentedType as ArrayType, rawArraySlice));
        }

        ISemantic E(PostfixExpression_Increment x, ISemantic foreExpression)
        {
            // myInt++ is still of type 'int'
            if (!eval)
            {
                return(foreExpression);
            }

            if (resolveConstOnly)
            {
                EvalError(new NoConstException(x));
            }
            // Must be implemented anyway regarding ctfe
            return(null);
        }

        ISemantic E(PostfixExpression_Decrement x, ISemantic foreExpression)
        {
            if (!eval)
            {
                return(foreExpression);
            }

            if (resolveConstOnly)
            {
                EvalError(new NoConstException(x));
            }
            // Must be implemented anyway regarding ctfe
            return(null);
        }
    }
}
Пример #30
0
 public static AbstractType[] GetAccessedOverloads(PostfixExpression_Access acc, ResolutionContext ctxt,
                                                   ISemantic resultBase = null, bool DeducePostfixTemplateParams = true)
 {
     return(Evaluation.EvalPostfixAccessExpression <AbstractType>(new ExpressionTypeEvaluation(ctxt), ctxt, acc, resultBase, DeducePostfixTemplateParams));
 }
Пример #31
0
 public override void Visit(PostfixExpression_Access x)
 {
     if (IsIncompleteExpression(x.AccessExpression)) {
         halt = true;
         if (x.PostfixForeExpression is DTokenDeclaration && (x.PostfixForeExpression as DTokenDeclaration).Token == DTokens.Dot) {
             // Handle module-scoped things:
             // When typing a dot without anything following, trigger completion and show types, methods and vars that are located in the module & import scope
             prv = new CtrlSpaceCompletionProvider (cdgen, scopedBlock, null, MemberFilter.Methods | MemberFilter.Types | MemberFilter.Variables | MemberFilter.TypeParameters );
         }
         else
             prv = new MemberCompletionProvider (cdgen, x.PostfixForeExpression, scopedBlock, scopedStatement);
     }
     else
         base.Visit (x);
 }
        /// <summary>
        /// Returns either all unfiltered and undeduced overloads of a member of a base type/value (like b from type a if the expression is a.b).
        /// if <param name="EvalAndFilterOverloads"></param> is false.
        /// If true, all overloads will be deduced, filtered and evaluated, so that (in most cases,) a one-item large array gets returned
        /// which stores the return value of the property function b that is executed without arguments.
        /// Also handles UFCS - so if filtering is wanted, the function becom
        /// </summary>
        public static R[] EvalPostfixAccessExpression <R>(ExpressionVisitor <R> vis, ResolutionContext ctxt, PostfixExpression_Access acc,
                                                          ISemantic resultBase = null, bool EvalAndFilterOverloads = true, bool ResolveImmediateBaseType = true, AbstractSymbolValueProvider ValueProvider = null)
            where R : class, ISemantic
        {
            if (acc == null)
            {
                return(null);
            }

            var baseExpression = resultBase ?? (acc.PostfixForeExpression != null ? acc.PostfixForeExpression.Accept(vis) as ISemantic : null);

            if (acc.AccessExpression is NewExpression)
            {
                /*
                 * This can be both a normal new-Expression as well as an anonymous class declaration!
                 */
                //TODO!
                return(null);
            }


            AbstractType[] overloads;
            var            optBackup = ctxt.CurrentContext.ContextDependentOptions;

            if (acc.AccessExpression is TemplateInstanceExpression)
            {
                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;
                }

                var tix = (TemplateInstanceExpression)acc.AccessExpression;
                // Do not deduce and filter if superior expression is a method call since call arguments' types also count as template arguments!
                overloads = ExpressionTypeEvaluation.GetOverloads(tix, ctxt, new[] { AbstractType.Get(baseExpression) }, EvalAndFilterOverloads);

                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions = optBackup;
                }
            }

            else if (acc.AccessExpression is IdentifierExpression)
            {
                var id = acc.AccessExpression as IdentifierExpression;

                if (ValueProvider != null && EvalAndFilterOverloads && baseExpression != null)
                {
                    var staticPropResult = StaticProperties.TryEvalPropertyValue(ValueProvider, baseExpression, id.ValueStringHash);
                    if (staticPropResult != null)
                    {
                        return new[] { (R)staticPropResult }
                    }
                    ;
                }

                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions |= ResolutionOptions.DontResolveBaseTypes;
                }

                overloads = ExpressionTypeEvaluation.GetOverloads(id, ctxt, AmbiguousType.TryDissolve(AbstractType.Get(baseExpression)), EvalAndFilterOverloads);

                if (!ResolveImmediateBaseType)
                {
                    ctxt.CurrentContext.ContextDependentOptions = optBackup;
                }
            }
            else
            {            /*
                          *     if (eval){
                          *             EvalError(acc, "Invalid access expression");
                          *             return null;
                          *     }*/
                ctxt.LogError(acc, "Invalid post-dot expression");
                return(null);
            }

            // If evaluation active and the access expression is stand-alone, return a single item only.
            if (EvalAndFilterOverloads && ValueProvider != null)
            {
                return new[] { (R) new Evaluation(ValueProvider).TryDoCTFEOrGetValueRefs(AmbiguousType.Get(overloads, acc.AccessExpression), acc.AccessExpression) }
            }
            ;

            return(overloads as R[]);
        }

        ISymbolValue EvalForeExpression(PostfixExpression ex)
        {
            return(ex.PostfixForeExpression != null?ex.PostfixForeExpression.Accept(this) : null);
        }
        public static AbstractType[] GetAccessedOverloads(PostfixExpression_Access acc, ResolutionContext ctxt,
			ISemantic resultBase = null, bool DeducePostfixTemplateParams = true)
        {
            return TypeDeclarationResolver.Convert(new Evaluation(ctxt).E(acc, resultBase, DeducePostfixTemplateParams));
        }
Пример #34
0
 public void Visit(PostfixExpression_Access x)
 {
 }
Пример #35
0
        IExpression HexFloat()
        {
            bool neg = false;

            sb.Clear();
            if (r.Peek() == 'N')
            {
                r.Read();
                if (r.Peek() == 'A')
                {
                    sb.Append('A');
                    r.Read();
                    if (r.Peek() == 'N')
                    {
                        r.Read();
                        return(new PostfixExpression_Access {
                            AccessExpression = new IdentifierExpression("nan"), PostfixForeExpression = new TokenExpression(DTokens.Float)
                        });
                    }
                }
                neg = true;
            }

            if (r.Peek() == 'I')
            {
                r.Read();                 // Skip I
                r.Read();                 // Skip N
                r.Read();                 // Skip F
                var inf = new PostfixExpression_Access {
                    AccessExpression = new IdentifierExpression("infinity"), PostfixForeExpression = new TokenExpression(DTokens.Float)
                };

                if (neg)
                {
                    return new UnaryExpression_Sub {
                               UnaryExpression = inf
                    }
                }
                ;
                return(inf);
            }

            var n = HexDigits(false);

            if (neg)
            {
                n *= -1;
            }

            if (r.Peek() == 'P')
            {
                r.Read();
                var exp = Exponent();
                n *= (decimal)Math.Pow(10, exp);
            }

            return(new IdentifierExpression(n, LiteralFormat.Scalar | ((Math.Truncate(n) == n) ? 0 : LiteralFormat.FloatingPoint), LiteralSubformat.Double));
        }

        string LName(int len = -1)
        {
            if (len < 0)
            {
                len = (int)Number();
            }

            if (len == 0)
            {
                return(string.Empty);
            }

            var chs = new char[len];

            for (int i = 0; i < len; i++)
            {
                chs[i] = (char)r.Read();
            }

            return(new String(chs));
        }

        bool PeekIsDecNumber
        {
            get{
                var d = (char)r.Peek();
                return(Lexer.IsLegalDigit(d, 10) && d != '_');
            }
        }

        int Exponent()
        {
            if ((char)r.Peek() == 'N')
            {
                r.Read();
                return(-(int)Number());
            }
            return((int)Number());
        }

        decimal HexDigits(bool clearSb = true)
        {
            if (clearSb)
            {
                sb.Clear();
            }
            while (Lexer.IsHex((char)r.Peek()))
            {
                sb.Append((char)r.Read());
            }

            return(Lexer.ParseFloatValue(sb, 16));
        }

        decimal Number(bool clearSb = true)
        {
            if (clearSb)
            {
                sb.Clear();
            }
            while (PeekIsDecNumber)
            {
                sb.Append((char)r.Read());
            }

            return(Lexer.ParseFloatValue(sb, 10));
        }

        #endregion
    }
Пример #36
0
        public override void Visit(PostfixExpression_Access acc)
        {
            var resolvedSymbol = TryPopPFAStack ();

            if ((acc.AccessExpression is IdentifierExpression &&
                (acc.AccessExpression as IdentifierExpression).ValueStringHash != searchHash) ||
                (acc.AccessExpression is TemplateInstanceExpression &&
                ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash)) {
                acc.PostfixForeExpression.Accept (this);
                return;
            } else if (acc.AccessExpression is NewExpression) {
                var nex = acc.AccessExpression as NewExpression;

                if ((nex.Type is IdentifierDeclaration &&
                    ((IdentifierDeclaration)nex.Type).IdHash != searchHash) ||
                    (nex.Type is TemplateInstanceExpression &&
                    ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash != searchHash)) {
                    acc.PostfixForeExpression.Accept (this);
                    return;
                }
                // Are there other types to test for?
            } else {
                // Are there other types to test for?
            }

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

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

            // Scan down for other possible symbols
            if(s.Base is DSymbol)
                postfixForeExprAccessStack.Push (s.Base as DSymbol);
            acc.PostfixForeExpression.Accept (this);
        }
		List<IExpression> DoPrimaryIdCheck(PostfixExpression_Access acc)
		{
			var r = new List<IExpression>();
			while(acc != null){
				if (DoPrimaryIdCheck(ExtractId(acc)))
					r.Add(acc);

				// Scan down the access expression for other, deeper expressions
				if (acc.PostfixForeExpression is PostfixExpression_Access)
					acc = (PostfixExpression_Access)acc.PostfixForeExpression;
				else
				{
					if (DoPrimaryIdCheck(ExtractId(acc.PostfixForeExpression)))
						r.Add(acc.PostfixForeExpression);
					break;
				}
			}
			return r;
		}
Пример #38
0
        IExpression HexFloat()
        {
            bool neg = false;
            sb.Clear();
            if(r.Peek() == 'N')
            {
                r.Read();
                if(r.Peek() == 'A')
                {
                    sb.Append('A');
                    r.Read();
                    if(r.Peek() == 'N')
                    {
                        r.Read();
                        return new PostfixExpression_Access{ AccessExpression = new IdentifierExpression("nan"), PostfixForeExpression = new TokenExpression(DTokens.Float) };
                    }
                }
                neg = true;
            }

            if(r.Peek() == 'I')
            {
                r.Read(); // Skip I
                r.Read(); // Skip N
                r.Read(); // Skip F
                var inf = new PostfixExpression_Access{ AccessExpression = new IdentifierExpression("infinity"), PostfixForeExpression = new TokenExpression(DTokens.Float) };

                if(neg)
                    return new UnaryExpression_Sub{ UnaryExpression = inf };
                return inf;
            }

            var n = HexDigits(false);

            if(neg)
                n *= -1;

            if(r.Peek() == 'P')
            {
                r.Read();
                var exp = Exponent();
                n *= (decimal)Math.Pow(10, exp);
            }

            return new IdentifierExpression(n, LiteralFormat.Scalar | ((Math.Truncate(n) == n) ? 0 : LiteralFormat.FloatingPoint), LiteralSubformat.Double);
        }
Пример #39
0
        public static MemberSymbol[] TryResolveUFCS(
            ISemantic firstArgument,
            PostfixExpression_Access acc,
            ResolutionContext ctxt)
        {
            if (ctxt == null)
            {
                return(null);
            }

            int name = 0;

            if (acc.AccessExpression is IdentifierExpression)
            {
                name = ((IdentifierExpression)acc.AccessExpression).ValueStringHash;
            }
            else if (acc.AccessExpression is TemplateInstanceExpression)
            {
                name = ((TemplateInstanceExpression)acc.AccessExpression).TemplateIdHash;
            }
            else
            {
                return(null);
            }

            var methodMatches = new List <MemberSymbol>();

            if (ctxt.ParseCache != null)
            {
                foreach (var pc in ctxt.ParseCache)
                {
                    var tempResults = pc.UfcsCache.FindFitting(ctxt, acc.Location, firstArgument, name);

                    if (tempResults != null)
                    {
                        foreach (var m in tempResults)
                        {
                            ctxt.PushNewScope(m);

                            if (m.TemplateParameters != null && m.TemplateParameters.Length != 0)
                            {
                                var ov = TemplateInstanceHandler.DeduceParamsAndFilterOverloads(
                                    new[] { new MemberSymbol(m, null, acc) },
                                    new[] { firstArgument }, true, ctxt);

                                if (ov == null || ov.Length == 0)
                                {
                                    continue;
                                }

                                var ms = (DSymbol)ov[0];
                                ctxt.CurrentContext.IntroduceTemplateParameterTypes(ms);
                            }

                            var mr = TypeDeclarationResolver.HandleNodeMatch(m, ctxt, null, acc) as MemberSymbol;
                            if (mr != null)
                            {
                                mr.FirstArgument = firstArgument;
                                mr.DeducedTypes  = ctxt.CurrentContext.DeducedTemplateParameters.ToReadonly();
                                mr.IsUFCSResult  = true;
                                methodMatches.Add(mr);
                            }
                            ctxt.Pop();
                        }
                    }
                }
            }

            return(methodMatches.Count == 0 ? null : methodMatches.ToArray());
        }