Esempio n. 1
0
        public override ICodeNode VisitPropertyReferenceExpression(PropertyReferenceExpression node)
        {
            MethodReferenceExpression methodRefExpression = node.MethodExpression;

            if (methodRefExpression.Target != null)
            {
                if (methodRefExpression.Target.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                    asyncData.AwaiterVariables.Contains((methodRefExpression.Target as VariableReferenceExpression).Variable))
                {
                    VariableReference awaiterVariable = (methodRefExpression.Target as VariableReferenceExpression).Variable;
                    if (currentAwaiterVariable == awaiterVariable)
                    {
                        if (methodRefExpression.Method.Name == "get_IsCompleted")
                        {
                            if (matcherState == MatcherState.FindIsCompletedInvoke)
                            {
                                matcherState = MatcherState.FindInitObj | MatcherState.FindGetResultInvoke;
                                return(null);
                            }
                        }
                    }
                    matcherState = MatcherState.Stopped;
                    return(node);
                }
            }
            return(base.VisitPropertyReferenceExpression(node));
        }
        private bool Match()
        {
			if (this.originalStatements.Count == 0)
			{
				return false;
			}

			if (!this.methodContext.Method.IsAsync(out this.stateMachineTypeDef))
			{
				if (!this.methodContext.Method.HasAsyncAttributes() || !IsAsyncFirstAssignmentStatement(this.originalStatements[0], out this.stateMachineTypeDef) ||
					!this.methodContext.Method.HasAsyncStateMachineVariable())
				{
					return false;
				}
			}

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

			asyncStatements = GetMoveNextStatements();
            if (asyncStatements == null || !TryRemoveOuterTryCatch(asyncStatements))
            {
                return false;
            }

            SetParameterMappings(originalStatements);

            matcherState = MatcherState.FindAwaitExpression;
            asyncStatements = (StatementCollection)Visit(asyncStatements);

			bool result = matcherState == MatcherState.FindAwaitExpression;
            return result;
        }
Esempio n. 3
0
 //    Start a pattern match at the beginning with one object.
 internal PatternMatcher(ProseRuntime runtime)
 {
     this.runtime = runtime;
     patternTrie = runtime.GlobalScope.PatternTree;
     state = MatcherState.MATCHING_OBJECT;
     currNode = patternTrie.Root;
 }
Esempio n. 4
0
        private void while_MATCHING_TEXT_extendWith(PNode node, Trie <ProseObject, List <Phrase> > .Node patternNode)
        {
            this.numObjectsMatched++;
            this.currNode = patternNode;

            if (node.value == runtime.Quadquote)
            {
                textMatchingQQcount++;
                //	If this is the first time through, record the beginning of the text block
                if (textMatchingQQcount == 1)
                {
                    patternComponentNodes.Add(node);
                }
            }

            //	We become matched when the text ends.
            if (currNode.Value != null && currNode.Value.Count != 0 &&
                textMatchingQQcount == 2)
            {
                //isMatched = true;
                becomeMatched(node.next);
            }
            else if (textMatchingQQcount > 2)
            {
                state = MatcherState.FAILED;
            }
            else if (textMatchingQQcount == 2)
            {
                switchToState_MATCHING_OBJECT();
            }
        }
Esempio n. 5
0
 //	Start a pattern match at the beginning with one object.
 internal PatternMatcher(ProseRuntime runtime)
 {
     this.runtime = runtime;
     patternTrie  = runtime.GlobalScope.PatternTree;
     state        = MatcherState.MATCHING_OBJECT;
     currNode     = patternTrie.Root;
 }
Esempio n. 6
0
        public override ICodeNode VisitBinaryExpression(BinaryExpression node)
        {
            if (node.Operator == BinaryOperator.Assign)
            {
                if (node.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                    asyncData.AwaiterVariables.Contains((node.Left as VariableReferenceExpression).Variable))
                {
                    VariableReference awaiterVariable = (node.Left as VariableReferenceExpression).Variable;

                    if (node.Right.CodeNodeType == CodeNodeType.MethodInvocationExpression &&
                        (node.Right as MethodInvocationExpression).MethodExpression.Method.Name == "GetAwaiter")
                    {
                        Expression expression = null;//(Expression)Visit((node.Right as MethodInvocationExpression).MethodExpression.Target);
                        MethodInvocationExpression methodInvocation = node.Right as MethodInvocationExpression;
                        if (methodInvocation.MethodExpression.Target != null)
                        {
                            if (methodInvocation.Arguments.Count == 0)
                            {
                                expression = (Expression)Visit(methodInvocation.MethodExpression.Target);
                            }
                        }
                        else
                        {
                            if (methodInvocation.Arguments.Count == 1)
                            {
                                expression = (Expression)Visit(methodInvocation.Arguments[0]);
                            }
                        }

                        if (expression != null && matcherState == MatcherState.FindAwaitExpression)
                        {
                            currentAwaiterVariable = awaiterVariable;
                            awaitedExpression      = expression;
                            matcherState           = MatcherState.FindIsCompletedInvoke;
                            return(null);
                        }
                    }
                    else if ((node.Right.CodeNodeType == CodeNodeType.ObjectCreationExpression) ||
                             ((node.Right.CodeNodeType == CodeNodeType.LiteralExpression) && ((node.Right as LiteralExpression).Value == null)))
                    {
                        if ((matcherState & MatcherState.FindInitObj) == MatcherState.FindInitObj &&
                            currentAwaiterVariable == awaiterVariable)
                        {
                            matcherState ^= MatcherState.FindInitObj;
                            return(null);
                        }
                    }

                    matcherState = MatcherState.Stopped;
                    return(node);
                }
                else if (node.Left.CodeNodeType == CodeNodeType.FieldReferenceExpression &&
                         (node.Left as FieldReferenceExpression).Field.Resolve() == asyncData.StateField ||
                         node.Right.CodeNodeType == CodeNodeType.ThisReferenceExpression)
                {
                    return(null);
                }
            }
            return(base.VisitBinaryExpression(node));
        }
Esempio n. 7
0
        private void switchToState_MATCHING_PROSE()
        {
            state = MatcherState.MATCHING_PROSE;

            //	Create a new block to hold the building Prose.
            proseBlock                 = new ProseBlockObject();
            parentheticalStack         = new Stack <ProseObject>();
            objectsInCurrentProseblock = 0;
        }
Esempio n. 8
0
        private void switchToState_MATCHING_PATTERN()
        {
            state = MatcherState.MATCHING_PATTERN;

            //	Counts 1 when hits [, increments for each word.  When it gets
            //	to ] it makes sure the count is at 2.  More words is illegal, no words is illegal.
            //	Also, checks that the words are words or RawWords.
            bracketReaderCount     = 0;
            prevBracketReaderCount = 0;
            if (currPatternObject == null)
            {
                currPatternObject = new PatternObject();
            }
        }
Esempio n. 9
0
        public override ICodeNode VisitMethodInvocationExpression(MethodInvocationExpression node)
        {
            MethodReferenceExpression methodRefExpression = node.MethodExpression;

            if (methodRefExpression.Target != null)
            {
                if (methodRefExpression.Target.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                    asyncData.AwaiterVariables.Contains((methodRefExpression.Target as VariableReferenceExpression).Variable))
                {
                    VariableReference awaiterVariable = (methodRefExpression.Target as VariableReferenceExpression).Variable;
                    if (currentAwaiterVariable == awaiterVariable)
                    {
                        if (methodRefExpression.Method.Name == "get_IsCompleted")
                        {
                            if (matcherState == MatcherState.FindIsCompletedInvoke)
                            {
                                matcherState = MatcherState.FindInitObj | MatcherState.FindGetResultInvoke;
                                return(null);
                            }
                        }
                        else if (methodRefExpression.Method.Name == "GetResult")
                        {
                            if ((matcherState & MatcherState.FindGetResultInvoke) == MatcherState.FindGetResultInvoke)
                            {
                                matcherState ^= MatcherState.FindGetResultInvoke;
                                return(new AwaitExpression((Expression)Visit(awaitedExpression), methodRefExpression.Method.ReturnType, node.UnderlyingSameMethodInstructions));
                            }
                        }
                    }

                    matcherState = MatcherState.Stopped;
                    return(node);
                }
                else if (methodRefExpression.Target.CodeNodeType == CodeNodeType.FieldReferenceExpression &&
                         (methodRefExpression.Target as FieldReferenceExpression).Field.Resolve() == builderField)
                {
                    if (methodRefExpression.Method.Name == "SetResult")
                    {
                        Expression returnValue = node.Arguments.Count > 0 ? node.Arguments[0] : null;
                        return(new ReturnExpression(returnValue, methodRefExpression.UnderlyingSameMethodInstructions));
                    }
                }
            }
            return(base.VisitMethodInvocationExpression(node));
        }
        private bool Match()
        {
            if (this.originalStatements.Count == 0)
            {
                return(false);
            }

            if (!this.methodContext.Method.IsAsync(out this.stateMachineTypeDef))
            {
                if (!this.methodContext.Method.HasAsyncAttributes() || !IsAsyncFirstAssignmentStatement(this.originalStatements[0], out this.stateMachineTypeDef) ||
                    !this.methodContext.Method.HasAsyncStateMachineVariable())
                {
                    return(false);
                }
            }

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

            asyncStatements = GetMoveNextStatements();
            if (asyncStatements == null || !TryRemoveOuterTryCatch(asyncStatements))
            {
                return(false);
            }

            SetParameterMappings(originalStatements);

            matcherState    = MatcherState.FindAwaitExpression;
            asyncStatements = (StatementCollection)Visit(asyncStatements);

            // The C# compiler that comes with MSBuild 15.0 (VS 2017 and .NET Core) seems to produce different code that the one coming with
            // MSBuild 14.0 (VS 2015) and the ones before that. In the new one there is one missing object initialization (when matcherState
            // is MatcherState.FindInitObj this step is searching for it) and this is causing our pattern matching to fail.
            // "|| matcherState == MatcherState.FindInitObj" is quick and dirty fix, which can be improved but due to the limited time right now,
            // I'm leaving it that way.
            bool result = matcherState == MatcherState.FindAwaitExpression || matcherState == MatcherState.FindInitObj;

            return(result);
        }
Esempio n. 11
0
        private bool Match()
        {
            if (this.originalStatements.Count == 0)
            {
                return(false);
            }

            if (!this.methodContext.Method.IsAsync(out this.stateMachineTypeDef))
            {
                if (!this.methodContext.Method.HasAsyncAttributes() || !IsAsyncFirstAssignmentStatement(this.originalStatements[0], out this.stateMachineTypeDef) ||
                    !this.methodContext.Method.HasAsyncStateMachineVariable())
                {
                    return(false);
                }
            }

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

            asyncStatements = GetMoveNextStatements();
            if (asyncStatements == null || !TryRemoveOuterTryCatch(asyncStatements))
            {
                return(false);
            }

            SetParameterMappings(originalStatements);

            matcherState    = MatcherState.FindAwaitExpression;
            asyncStatements = (StatementCollection)Visit(asyncStatements);

            bool result = matcherState == MatcherState.FindAwaitExpression;

            return(result);
        }
Esempio n. 12
0
 private void switchToState_MATCHING_OBJECT()
 {
     state = MatcherState.MATCHING_OBJECT;
 }
Esempio n. 13
0
 private void switchToState_MATCHING_TEXT()
 {
     state = MatcherState.MATCHING_TEXT;
     textMatchingQQcount = 0;
 }
Esempio n. 14
0
        private void switchToState_MATCHING_PROSE()
        {
            state = MatcherState.MATCHING_PROSE;

            //	Create a new block to hold the building Prose.
            proseBlock = new ProseBlockObject();
            parentheticalStack = new Stack<ProseObject>();
            objectsInCurrentProseblock = 0;
        }
Esempio n. 15
0
        //    Read a new object and maybe switch to reading prose, text, or pattern if necessary.
        List<PatternMatcher> while_MATCHING_OBJECT_matchNextObject(PNode node)
        {
            ProseObject obj = node.value;
            //	Some symbols get special treatment at the beginning or end of
            if (	obj == runtime.Period
                ||	obj == runtime.Semicolon
                &&	currNode == patternTrie.Root)
            {

            }

            //	Get a list of words which, if they appeared in a pattern, would match with this one.
            List<ProseObject> matchingPatternWords = getMatchingPatternWords(obj);

            //
            //	For each matchingPatternWord, query the pattern tree to see if
            //	our pattern can be extended any further.
            //

            List<PatternMatcher> babyMatchers = new List<PatternMatcher>(16);

            bool foundAMatch = false;
            //ProseObject myExtensionObject = null;
            Trie<ProseObject, List<Phrase>>.Node myExtensionNode = null;
            foreach(ProseObject objMatch in matchingPatternWords)
            {
                ProseObject match = objMatch;

                //Word match = (Word) objMatch;
                //	Look up the node that would correspond to the pattern word that would match.
                Trie<ProseObject, List<Phrase>>.Node matchNode = currNode.getChildNode(match);
                //	If we can't find it, then there are no patterns with that matching word, so skip it
                if (matchNode == null)
                    continue;
                //	If we can find it, then we might need to make a new matcher
                //	Since ONE match has to be reserved for THIS, and the other matches spawn new matchers,
                //	we use "foundAMatch" to decide which to do.
            //				if (foundAMatch)
            //				{
                    //	Spawn off a baby matcher and transform its state to represent the new possibility.
                PatternMatcher babyMatcher = this.makeCopyWithStateFromAtWord(match);
                babyMatcher.while_MATCHING_OBJECT_extendWith(node, matchNode);
                babyMatchers.Add(babyMatcher);		//	List this baby matcher
                foundAMatch = true;
            //				}
            //				else {
            //					//	Cache these two so we can use them later.
            //					myExtensionObject = match;
            //					myExtensionNode = matchNode;
            //					foundAMatch = true;
            //				}
            }

            //	If we found at least one, then we need to tweak ourselves and add ourselves to the babies.
            //			if (foundAMatch) {
            //				this.while_MATCHING_OBJECT_extendWith(node, myExtensionNode);
            //				babyMatchers.Add(this);
            //			}
            //			else {
            //				state = MatcherState.FAILED;
            //			}

            if (!foundAMatch) {
                state = MatcherState.FAILED;
            }
            return babyMatchers;
        }
Esempio n. 16
0
        private void while_MATCHING_PATTERN_extendWith(PNode node, Trie <ProseObject, List <Phrase> > .Node patternNode)
        {
            //	If this is the first node we're pushing in as a "pattern", then add it to patternComponentNodes
            if (currPatternObject.Length == 0)
            {
                patternComponentNodes.Add(node);
            }

            ProseObject obj = node.value;

            switch (bracketReaderCount)
            {
            case 0:
                if (obj == runtime.LeftSquareBracket)
                {
                    //	Attempting to name an argument when no argument type preceeds it!
                    if (currPatternObject.Length == 0)
                    {
                        state = MatcherState.FAILED;
                        return;
                    }
                    numObjectsMatched++;
                    setBracketReaderCount(1);
                }
                else
                {
                    if (obj is Word)
                    {
                        currPatternObject.putPatternElement(obj);
                        numObjectsMatched++;
                    }
                    else
                    {
                        state = MatcherState.FAILED;
                        return;
                    }
                }
                break;

            case 1:
                if (obj == runtime.RightSquareBracket)
                {
                    justPutArgName = false;
                    setBracketReaderCount(0);
                    numObjectsMatched++;
                }
                //	If its a word or raw word then it should be an argument name
                else if (obj is Word || obj is RawWord)
                {
                    if (!justPutArgName)
                    {
                        currPatternObject.replaceLastPutElementNameWith(obj);
                        justPutArgName = true;
                        numObjectsMatched++;
                    }
                    else
                    {
                        //	Can't supply two arg names.
                        state = MatcherState.FAILED;
                        return;
                    }
                }
                break;
            }

            //	VERY IMPORTANT:  Keep the matcher moving up the tree.
            currNode = patternNode;
        }
Esempio n. 17
0
 private void switchToState_MATCHING_TEXT()
 {
     state = MatcherState.MATCHING_TEXT;
     textMatchingQQcount = 0;
 }
Esempio n. 18
0
        private void while_MATCHING_PATTERN_extendWith(PNode node, Trie<ProseObject, List<Phrase>>.Node patternNode)
        {
            //	If this is the first node we're pushing in as a "pattern", then add it to patternComponentNodes
            if (currPatternObject.Length == 0) {
                patternComponentNodes.Add(node);
            }

            ProseObject obj = node.value;
            switch (bracketReaderCount)
            {
            case 0:
                if (obj == runtime.LeftSquareBracket) {
                    //	Attempting to name an argument when no argument type preceeds it!
                    if (currPatternObject.Length == 0) {
                        state = MatcherState.FAILED;
                        return;
                    }
                    numObjectsMatched++;
                    setBracketReaderCount(1);
                }
                else {
                    if (obj is Word) {
                        currPatternObject.putPatternElement(obj);
                        numObjectsMatched++;
                    }
                    else {
                        state = MatcherState.FAILED;
                        return;
                    }
                }
                break;

            case 1:
                if (obj == runtime.RightSquareBracket) {
                    justPutArgName = false;
                    setBracketReaderCount(0);
                    numObjectsMatched++;
                }
                //	If its a word or raw word then it should be an argument name
                else if (obj is Word  ||  obj is RawWord) {
                    if (!justPutArgName) {
                        currPatternObject.replaceLastPutElementNameWith(obj);
                        justPutArgName = true;
                        numObjectsMatched++;
                    }
                    else {
                        //	Can't supply two arg names.
                        state = MatcherState.FAILED;
                        return;
                    }
                }
                break;
            }

            //	VERY IMPORTANT:  Keep the matcher moving up the tree.
            currNode = patternNode;
        }
Esempio n. 19
0
        private void while_MATCHING_TEXT_extendWith(PNode node, Trie<ProseObject, List<Phrase>>.Node patternNode)
        {
            this.numObjectsMatched++;
            this.currNode = patternNode;

            if (node.value == runtime.Quadquote) {
                textMatchingQQcount++;
                //	If this is the first time through, record the beginning of the text block
                if (textMatchingQQcount == 1) {
                    patternComponentNodes.Add(node);
                }
            }

            //	We become matched when the text ends.
            if (	currNode.Value != null && currNode.Value.Count != 0
                &&	textMatchingQQcount == 2)
            {
                //isMatched = true;
                becomeMatched(node.next);
            }
            else if (textMatchingQQcount > 2)
            {
                state = MatcherState.FAILED;
            }
            else if (textMatchingQQcount == 2)
            {
                switchToState_MATCHING_OBJECT();
            }
        }
Esempio n. 20
0
        //	Read a new object and maybe switch to reading prose, text, or pattern if necessary.
        List <PatternMatcher> while_MATCHING_OBJECT_matchNextObject(PNode node)
        {
            ProseObject obj = node.value;

            //	Some symbols get special treatment at the beginning or end of
            if (obj == runtime.Period ||
                obj == runtime.Semicolon &&
                currNode == patternTrie.Root)
            {
            }

            //	Get a list of words which, if they appeared in a pattern, would match with this one.
            List <ProseObject> matchingPatternWords = getMatchingPatternWords(obj);

            //
            //	For each matchingPatternWord, query the pattern tree to see if
            //	our pattern can be extended any further.
            //

            List <PatternMatcher> babyMatchers = new List <PatternMatcher>(16);

            bool foundAMatch = false;

            //ProseObject myExtensionObject = null;
            Trie <ProseObject, List <Phrase> > .Node myExtensionNode = null;
            foreach (ProseObject objMatch in matchingPatternWords)
            {
                ProseObject match = objMatch;



                //Word match = (Word) objMatch;
                //	Look up the node that would correspond to the pattern word that would match.
                Trie <ProseObject, List <Phrase> > .Node matchNode = currNode.getChildNode(match);
                //	If we can't find it, then there are no patterns with that matching word, so skip it
                if (matchNode == null)
                {
                    continue;
                }
                //	If we can find it, then we might need to make a new matcher
                //	Since ONE match has to be reserved for THIS, and the other matches spawn new matchers,
                //	we use "foundAMatch" to decide which to do.
//				if (foundAMatch)
//				{
                //	Spawn off a baby matcher and transform its state to represent the new possibility.
                PatternMatcher babyMatcher = this.makeCopyWithStateFromAtWord(match);
                babyMatcher.while_MATCHING_OBJECT_extendWith(node, matchNode);
                babyMatchers.Add(babyMatcher);                          //	List this baby matcher
                foundAMatch = true;
//				}
//				else {
//					//	Cache these two so we can use them later.
//					myExtensionObject = match;
//					myExtensionNode = matchNode;
//					foundAMatch = true;
//				}
            }

            //	If we found at least one, then we need to tweak ourselves and add ourselves to the babies.
//			if (foundAMatch) {
//				this.while_MATCHING_OBJECT_extendWith(node, myExtensionNode);
//				babyMatchers.Add(this);
//			}
//			else {
//				state = MatcherState.FAILED;
//			}

            if (!foundAMatch)
            {
                state = MatcherState.FAILED;
            }
            return(babyMatchers);
        }
Esempio n. 21
0
        private void switchToState_MATCHING_PATTERN()
        {
            state = MatcherState.MATCHING_PATTERN;

            //	Counts 1 when hits [, increments for each word.  When it gets
            //	to ] it makes sure the count is at 2.  More words is illegal, no words is illegal.
            //	Also, checks that the words are words or RawWords.
            bracketReaderCount = 0;
            prevBracketReaderCount = 0;
            if (currPatternObject == null)
                currPatternObject = new PatternObject();
        }
        public override ICodeNode VisitMethodInvocationExpression(MethodInvocationExpression node)
        {
            MethodReferenceExpression methodRefExpression = node.MethodExpression;
            if (methodRefExpression.Target != null)
            {
                if (methodRefExpression.Target.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                    asyncData.AwaiterVariables.Contains((methodRefExpression.Target as VariableReferenceExpression).Variable))
                {
                    VariableReference awaiterVariable = (methodRefExpression.Target as VariableReferenceExpression).Variable;
                    if (currentAwaiterVariable == awaiterVariable)
                    {
                        if (methodRefExpression.Method.Name == "get_IsCompleted")
                        {
                            if (matcherState == MatcherState.FindIsCompletedInvoke)
                            {
                                matcherState = MatcherState.FindInitObj | MatcherState.FindGetResultInvoke;
                                return null;
                            }
                        }
                        else if (methodRefExpression.Method.Name == "GetResult")
                        {
                            if ((matcherState & MatcherState.FindGetResultInvoke) == MatcherState.FindGetResultInvoke)
                            {
                                matcherState ^= MatcherState.FindGetResultInvoke;
                                return new AwaitExpression((Expression)Visit(awaitedExpression), methodRefExpression.Method.ReturnType, node.UnderlyingSameMethodInstructions);
                            }
                        }
                    }

                    matcherState = MatcherState.Stopped;
                    return node;
                }
                else if (methodRefExpression.Target.CodeNodeType == CodeNodeType.FieldReferenceExpression &&
                    (methodRefExpression.Target as FieldReferenceExpression).Field.Resolve() == builderField)
                {
                    if (methodRefExpression.Method.Name == "SetResult")
                    {
                        Expression returnValue = node.Arguments.Count > 0 ? node.Arguments[0] : null;
                        return new ReturnExpression(returnValue, methodRefExpression.UnderlyingSameMethodInstructions);
                    }
                }
            }
            return base.VisitMethodInvocationExpression(node);
        }
 public override ICodeNode VisitPropertyReferenceExpression(PropertyReferenceExpression node)
 {
     MethodReferenceExpression methodRefExpression = node.MethodExpression;
     if (methodRefExpression.Target != null)
     {
         if (methodRefExpression.Target.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
             asyncData.AwaiterVariables.Contains((methodRefExpression.Target as VariableReferenceExpression).Variable))
         {
             VariableReference awaiterVariable = (methodRefExpression.Target as VariableReferenceExpression).Variable;
             if (currentAwaiterVariable == awaiterVariable)
             {
                 if (methodRefExpression.Method.Name == "get_IsCompleted")
                 {
                     if (matcherState == MatcherState.FindIsCompletedInvoke)
                     {
                         matcherState = MatcherState.FindInitObj | MatcherState.FindGetResultInvoke;
                         return null;
                     }
                 }
             }
             matcherState = MatcherState.Stopped;
             return node;
         }
     }
     return base.VisitPropertyReferenceExpression(node);
 }
        public override ICodeNode VisitBinaryExpression(BinaryExpression node)
        {
            if (node.Operator == BinaryOperator.Assign)
            {
                if (node.Left.CodeNodeType == CodeNodeType.VariableReferenceExpression &&
                    asyncData.AwaiterVariables.Contains((node.Left as VariableReferenceExpression).Variable))
                {
                    VariableReference awaiterVariable = (node.Left as VariableReferenceExpression).Variable;

                    if (node.Right.CodeNodeType == CodeNodeType.MethodInvocationExpression &&
                        (node.Right as MethodInvocationExpression).MethodExpression.Method.Name == "GetAwaiter")
                    {
                        Expression expression = null;//(Expression)Visit((node.Right as MethodInvocationExpression).MethodExpression.Target);
                        MethodInvocationExpression methodInvocation = node.Right as MethodInvocationExpression;
                        if (methodInvocation.MethodExpression.Target != null)
                        {
                            if(methodInvocation.Arguments.Count == 0)
                            {
                                expression = (Expression)Visit(methodInvocation.MethodExpression.Target);
                            }
                        }
                        else
                        {
                            if (methodInvocation.Arguments.Count == 1)
                            {
                                expression = (Expression)Visit(methodInvocation.Arguments[0]);
                            }
                        }

                        if (expression != null && matcherState == MatcherState.FindAwaitExpression)
                        {
                            currentAwaiterVariable = awaiterVariable;
                            awaitedExpression = expression;
                            matcherState = MatcherState.FindIsCompletedInvoke;
                            return null;
                        }
                    }
                    else if ( (node.Right.CodeNodeType == CodeNodeType.ObjectCreationExpression) ||
                        ((node.Right.CodeNodeType == CodeNodeType.LiteralExpression) && ((node.Right as LiteralExpression).Value == null)) )
                    {
                        if ((matcherState & MatcherState.FindInitObj) == MatcherState.FindInitObj &&
                            currentAwaiterVariable == awaiterVariable)
                        {
                            matcherState ^= MatcherState.FindInitObj;
                            return null;
                        }
                    }

                    matcherState = MatcherState.Stopped;
                    return node;
                }
                else if (node.Left.CodeNodeType == CodeNodeType.FieldReferenceExpression &&
                    (node.Left as FieldReferenceExpression).Field.Resolve() == asyncData.StateField ||
                    node.Right.CodeNodeType == CodeNodeType.ThisReferenceExpression)
                {
                    return null;
                }
            }
            return base.VisitBinaryExpression(node);
        }
Esempio n. 25
0
 private void switchToState_MATCHING_OBJECT()
 {
     state = MatcherState.MATCHING_OBJECT;
 }