コード例 #1
0
 /// <summary>
 ///     A user defined function parameter was never referenced.
 /// </summary>
 /// <param name="location">The location in the source code of the parameter that was never referenced.</param>
 /// <param name="parameter">The variable declaration node of the un-referenced function parameter.</param>
 /// <param name="inFunction">The signature of the function in which the parameter exists.</param>
 public virtual void FunctionParameterNeverUsed(LSLSourceCodeRange location,
                                                ILSLVariableDeclarationNode parameter,
                                                ILSLFunctionSignature inFunction)
 {
     OnWarning(location,
               string.Format("Parameter \"{0}\" was never used in function \"{1}\".", parameter.Name, inFunction.Name));
 }
コード例 #2
0
        /// <summary>
        ///     Determines if two function signatures match exactly (including return type), parameter names do not matter but
        ///     parameter types and variadic parameter status do.
        /// </summary>
        /// <param name="left">The first function signature in the comparison.</param>
        /// <param name="right">The other function signature in the comparison.</param>
        /// <returns>True if the two signatures are identical</returns>
        /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is <c>null</c>.</exception>
        public static bool SignaturesEquivalent(ILSLFunctionSignature left, ILSLFunctionSignature right)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }
            if (right == null)
            {
                throw new ArgumentNullException("right");
            }

            if (left.ReturnType != right.ReturnType)
            {
                return(false);
            }
            if (left.Name != right.Name)
            {
                return(false);
            }
            if (left.ParameterCount != right.ParameterCount)
            {
                return(false);
            }
            for (var i = 0; i < left.ParameterCount; i++)
            {
                var l = left.Parameters[i];
                var r = right.Parameters[i];
                if (l.Type != r.Type || l.Variadic != r.Variadic)
                {
                    return(false);
                }
            }
            return(true);
        }
コード例 #3
0
 /// <summary>
 ///     A local variable name inside of a user defined function hides the definition of one of the functions parameters.
 /// </summary>
 /// <param name="location">The location in source code of the local variable that hides the function parameter.</param>
 /// <param name="functionSignature">The signature of the function in which the local variable is defined.</param>
 /// <param name="localVariable">The variable declaration node of the local variable that hides the parameter.</param>
 /// <param name="parameter">The parameter node of the parameter that was hidden.</param>
 public virtual void LocalVariableHidesParameter(LSLSourceCodeRange location,
                                                 ILSLFunctionSignature functionSignature,
                                                 ILSLVariableDeclarationNode localVariable, ILSLParameterNode parameter)
 {
     OnWarning(location, string.Format("Local variable \"{0}\" in function \"{1}\" hides parameter \"{2}\".",
                                       localVariable.Name, functionSignature.Name, parameter.Name));
 }
コード例 #4
0
 void ILSLSyntaxWarningListener.FunctionParameterNeverUsed(LSLSourceCodeRange location,
                                                           ILSLVariableDeclarationNode parameter,
                                                           ILSLFunctionSignature inFunction)
 {
     _warningActionQueue.Enqueue(location.StartIndex,
                                 () => SyntaxWarningListener.FunctionParameterNeverUsed(location, parameter, inFunction));
 }
コード例 #5
0
 void ILSLSyntaxWarningListener.UseOfDeprecatedLibraryFunction(LSLSourceCodeRange location,
                                                               ILSLFunctionSignature functionSignature)
 {
     _warningActionQueue.Enqueue(location.StartIndex,
                                 () =>
                                 SyntaxWarningListener.UseOfDeprecatedLibraryFunction(location, functionSignature));
 }
コード例 #6
0
 /// <summary>
 ///     A library function that was marked as being deprecated was used.
 /// </summary>
 /// <param name="location">The location in source code where the deprecated function was called.</param>
 /// <param name="functionSignature">The function signature of the deprecated library function that was called.</param>
 public virtual void UseOfDeprecatedLibraryFunction(LSLSourceCodeRange location,
                                                    ILSLFunctionSignature functionSignature)
 {
     OnWarning(location,
               string.Format(
                   "The library function \"{0}\" is deprecated, it is recommended you use an alternative or remove it.",
                   functionSignature.Name));
 }
コード例 #7
0
        /// <summary>
        ///     A user defined local variable was never referenced.
        /// </summary>
        /// <param name="location">The location in the source code of the local variable that was never referenced.</param>
        /// <param name="variable">The variable declaration node of the un-referenced local variable.</param>
        /// <param name="inFunction">The signature of the function in which the local variable exists.</param>
        public virtual void LocalVariableNeverUsed(LSLSourceCodeRange location, ILSLVariableDeclarationNode variable,
                                                   ILSLFunctionSignature inFunction)
        {
            const string msg = "Local variable \"{0}\" was never used in function \"{1}\".";


            OnWarning(location, string.Format(msg, variable.Name, inFunction.Name));
        }
コード例 #8
0
 void ILSLSyntaxWarningListener.LocalVariableHidesParameter(LSLSourceCodeRange location,
                                                            ILSLFunctionSignature functionSignature,
                                                            ILSLVariableDeclarationNode localVariable, ILSLParameterNode parameter)
 {
     _warningActionQueue.Enqueue(location.StartIndex,
                                 () =>
                                 SyntaxWarningListener.LocalVariableHidesParameter(location, functionSignature, localVariable,
                                                                                   parameter));
 }
コード例 #9
0
 void ILSLSyntaxErrorListener.TypeMismatchInReturnValue(LSLSourceCodeRange location,
                                                        ILSLFunctionSignature functionSignature,
                                                        ILSLReadOnlyExprNode attemptedReturnExpression)
 {
     _errorActionQueue.Enqueue(location.StartIndex,
                               () =>
                               SyntaxErrorListener.TypeMismatchInReturnValue(location, functionSignature,
                                                                             attemptedReturnExpression));
 }
コード例 #10
0
 void ILSLSyntaxErrorListener.ParameterTypeMismatchInFunctionCall(LSLSourceCodeRange location,
                                                                  int parameterIndexWithError,
                                                                  ILSLFunctionSignature calledFunction, ILSLReadOnlyExprNode[] parameterExpressionsGiven)
 {
     _errorActionQueue.Enqueue(location.StartIndex,
                               () =>
                               SyntaxErrorListener.ParameterTypeMismatchInFunctionCall(location, parameterIndexWithError,
                                                                                       calledFunction, parameterExpressionsGiven));
 }
コード例 #11
0
 void ILSLSyntaxWarningListener.LocalVariableHidesGlobalVariable(LSLSourceCodeRange location,
                                                                 ILSLFunctionSignature functionSignature,
                                                                 ILSLVariableDeclarationNode localVariable, ILSLVariableDeclarationNode globalVariable)
 {
     _warningActionQueue.Enqueue(location.StartIndex,
                                 () =>
                                 SyntaxWarningListener.LocalVariableHidesGlobalVariable(location, functionSignature, localVariable,
                                                                                        globalVariable));
 }
コード例 #12
0
        /// <summary>
        ///     Determines if two function signatures match exactly (including return type), parameter names do not matter but
        ///     parameter types do.
        /// </summary>
        /// <param name="otherSignature">The other function signature to compare to</param>
        /// <returns>True if the two signatures are identical</returns>
        /// <exception cref="ArgumentNullException"><paramref name="otherSignature"/> is <c>null</c>.</exception>
        public bool SignatureEquivalent(ILSLFunctionSignature otherSignature)
        {
            if (otherSignature == null)
            {
                throw new ArgumentNullException("otherSignature");
            }

            return(LSLFunctionSignatureMatcher.SignaturesEquivalent(this, otherSignature));
        }
コード例 #13
0
 void ILSLSyntaxWarningListener.VariableRedeclaredInInnerScope(LSLSourceCodeRange location,
                                                               ILSLFunctionSignature currentFunctionBodySignature,
                                                               ILSLVariableDeclarationNode newDeclarationNode, ILSLVariableDeclarationNode previousDeclarationNode)
 {
     _warningActionQueue.Enqueue(location.StartIndex,
                                 () =>
                                 SyntaxWarningListener.VariableRedeclaredInInnerScope(location, currentFunctionBodySignature,
                                                                                      newDeclarationNode, previousDeclarationNode));
 }
コード例 #14
0
 void ILSLSyntaxErrorListener.ImproperParameterCountInFunctionCall(LSLSourceCodeRange location,
                                                                   ILSLFunctionSignature functionSignature,
                                                                   ILSLReadOnlyExprNode[] parameterExpressionsGiven)
 {
     _errorActionQueue.Enqueue(location.StartIndex,
                               () =>
                               SyntaxErrorListener.ImproperParameterCountInFunctionCall(location, functionSignature,
                                                                                        parameterExpressionsGiven));
 }
コード例 #15
0
 /// <summary>
 ///     A local variable was re-declared inside of a nested scope, such as an if statement or for loop, ect... <para/>
 ///     This is not an error, but bad practice. This function handles the warning case inside function declarations.
 /// </summary>
 /// <param name="location">The source code range of the new variable declaration.</param>
 /// <param name="currentFunctionBodySignature">The signature of the function the new variable was declared in.</param>
 /// <param name="newDeclarationNode">The tree node of the new declaration that has not been added to the tree yet.</param>
 /// <param name="previousDeclarationNode">
 ///     The previous variable declaration node which already exist in the syntax tree, in
 ///     an outer scope.
 /// </param>
 public virtual void VariableRedeclaredInInnerScope(LSLSourceCodeRange location,
                                                    ILSLFunctionSignature currentFunctionBodySignature,
                                                    ILSLVariableDeclarationNode newDeclarationNode, ILSLVariableDeclarationNode previousDeclarationNode)
 {
     OnWarning(location,
               string.Format(
                   "Local variable \"{0}\" in function \"{1}\" hides a previous declaration in an outer scope (on line {2}).",
                   newDeclarationNode.Name, currentFunctionBodySignature.Name,
                   MapLineNumber(previousDeclarationNode.SourceRange.LineStart)));
 }
コード例 #16
0
 /// <summary>
 ///     A local variable inside of a user defined function hides the definition of a user defined global variable.
 /// </summary>
 /// <param name="location">The location in source code of the local variable that hides the global variable.</param>
 /// <param name="functionSignature">The signature of the function in which the local variable is defined.</param>
 /// <param name="localVariable">The variable declaration node of the local variable that hides the global variable.</param>
 /// <param name="globalVariable">The variable declaration node of the user defined global variable that was hidden.</param>
 public virtual void LocalVariableHidesGlobalVariable(LSLSourceCodeRange location,
                                                      ILSLFunctionSignature functionSignature,
                                                      ILSLVariableDeclarationNode localVariable, ILSLVariableDeclarationNode globalVariable)
 {
     OnWarning(location,
               string.Format(
                   "Local variable \"{0}\" in function \"{1}\" hides global variable \"{2}\" defined on line {3}.",
                   localVariable.Name, functionSignature.Name, globalVariable.Name,
                   MapLineNumber(globalVariable.SourceRange.LineStart)));
 }
コード例 #17
0
        /// <summary>
        ///     Construct an <see cref="LSLFunctionSignature" /> by cloning another <see cref="LSLFunctionSignature" /> object.
        /// </summary>
        /// <param name="other">The <see cref="LSLFunctionSignature" /> object to copy construct from.</param>
        /// <exception cref="ArgumentNullException"><paramref name="other" /> is <c>null</c>.</exception>
        public LSLFunctionSignature(ILSLFunctionSignature other)
        {
            if (other == null)
            {
                throw new ArgumentNullException("other");
            }

            Name                   = other.Name;
            _parameters            = new GenericArray <LSLParameterSignature>(other.Parameters);
            ReturnType             = other.ReturnType;
            HasVariadicParameter   = other.HasVariadicParameter;
            VariadicParameterIndex = other.VariadicParameterIndex;
        }
コード例 #18
0
 /// <summary>
 ///     Dead code was detected, but it was not an error because it was inside a function with a void return type.
 /// </summary>
 /// <param name="location">The location in the source code.</param>
 /// <param name="currentFunction">The signature of the function that dead code was detected in.</param>
 /// <param name="deadSegment">An object describing the range of code that is considered to be dead.</param>
 public virtual void DeadCodeDetected(LSLSourceCodeRange location, ILSLFunctionSignature currentFunction,
                                      ILSLDeadCodeSegment deadSegment)
 {
     if (deadSegment.SourceRange.IsSingleLine)
     {
         OnWarning(location, "Unreachable code detected in function \"" + currentFunction.Name + "\".");
     }
     else
     {
         OnWarning(location,
                   string.Format(
                       "Unreachable code detected in function \"" + currentFunction.Name +
                       "\" between lines {0} and {1}.",
                       MapLineNumber(deadSegment.SourceRange.LineStart),
                       MapLineNumber(deadSegment.SourceRange.LineEnd)));
     }
 }
コード例 #19
0
        /// <summary>
        ///     Determines if a two LSLFunctionSignatures are duplicate definitions of each other.
        ///     <para>
        ///         The logic behind this is a bit different than <see cref="SignaturesEquivalent" />.
        ///         If the given function signatures have the same name, differing return types and no parameters; than this
        ///         function will return true
        ///         and <see cref="SignaturesEquivalent" /> will not.
        ///         If the given function signatures have differing return types, and the exact same parameter types/count; than
        ///         this function will return true
        ///         and <see cref="SignaturesEquivalent" /> will not.
        ///     </para>
        /// </summary>
        /// <param name="left">The first function signature in the comparison.</param>
        /// <param name="right">The other function signature in the comparison.</param>
        /// <returns>
        ///     True if the two signatures are duplicate definitions of each other, taking static overloading ambiguities into
        ///     account.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="left"/> or <paramref name="right"/> is <c>null</c>.</exception>
        public static bool DefinitionIsDuplicate(ILSLFunctionSignature left, ILSLFunctionSignature right)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }
            if (right == null)
            {
                throw new ArgumentNullException("right");
            }

            //Cannot be duplicates of each other if the name is different
            if (left.Name != right.Name)
            {
                return(false);
            }

            //Both functions have no parameters and the same name, they are duplicate definitions of each other.
            if (left.ParameterCount == right.ParameterCount && left.ParameterCount == 0)
            {
                return(true);
            }

            //we don't care about the return type, it does not make a function definition unique, it does not participate in overload resolution.

            //simple case, these functions cannot be a duplicate definition if they have a different parameter count.
            if (left.ParameterCount != right.ParameterCount)
            {
                return(false);
            }
            for (var i = 0; i < left.ParameterCount; i++)
            {
                //check all the parameters have identical specifications.
                //IE, type and variadic status.
                var l = left.Parameters[i];
                var r = right.Parameters[i];
                if (l.Type != r.Type || l.Variadic != r.Variadic)
                {
                    //nope, there was a mismatch.
                    return(false);
                }
            }

            //everything matched up, the return type was ignored, it does not matter.
            return(true);
        }
コード例 #20
0
        /// <summary>
        ///     Construct an <see cref="LSLFunctionCallNode" /> with an arguments list.
        ///     This represents a call to a library function, since it has no definition node.
        /// </summary>
        /// <param name="functionSignature">The signature of the library function.</param>
        /// <param name="argumentList">The argument list node.</param>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="functionSignature" /> or <paramref name="argumentList" /> is
        ///     <c>null</c>.
        /// </exception>
        public LSLFunctionCallNode(ILSLFunctionSignature functionSignature, LSLExpressionListNode argumentList)
        {
            if (functionSignature == null)
            {
                throw new ArgumentNullException("functionSignature");
            }
            if (argumentList == null)
            {
                throw new ArgumentNullException("argumentList");
            }


            Signature = new LSLFunctionSignature(functionSignature);

            Name = functionSignature.Name;

            ArgumentExpressionList        = argumentList;
            ArgumentExpressionList.Parent = this;

            _libraryFunction = true;
        }
コード例 #21
0
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="context" /> or <paramref name="signature" /> or
        ///     <paramref name="argumentExpressionList" /> is <c>null</c>.
        /// </exception>
        internal LSLFunctionCallNode(
            LSLParser.Expr_FunctionCallContext context,
            ILSLFunctionSignature signature,
            LSLExpressionListNode argumentExpressionList)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (signature == null)
            {
                throw new ArgumentNullException("signature");
            }

            if (argumentExpressionList == null)
            {
                throw new ArgumentNullException("argumentExpressionList");
            }


            Signature = signature;

            Name = context.function_name.Text;

            _libraryFunction              = true;
            ArgumentExpressionList        = argumentExpressionList;
            argumentExpressionList.Parent = this;

            SourceRange             = new LSLSourceCodeRange(context);
            SourceRangeOpenParenth  = new LSLSourceCodeRange(context.open_parenth);
            SourceRangeCloseParenth = new LSLSourceCodeRange(context.close_parenth);
            SourceRangeName         = new LSLSourceCodeRange(context.function_name);

            SourceRangesAvailable = true;
        }
コード例 #22
0
 /// <summary>
 ///     Check if a given function signature can be called with the given expressions as parameters
 /// </summary>
 /// <param name="expressionValidator">
 ///     The expression validator, which is used to determine if an expression can be passed
 ///     into a parameter of a certain type.
 /// </param>
 /// <param name="functionSignature">The function signature of the functions your passing the parameter expressions to.</param>
 /// <param name="expressions">The expressions we want to test against this function signatures defined parameters.</param>
 /// <returns>
 ///     A <see cref="LSLFunctionSignatureMatch"/> object containing information about how the parameters matched
 ///     or did not match the call signature.
 /// </returns>
 public static LSLFunctionSignatureMatch TryMatch(ILSLFunctionSignature functionSignature,
                                                  IReadOnlyGenericArray <ILSLReadOnlyExprNode> expressions, ILSLExpressionValidator expressionValidator)
 {
     return(TryMatch(functionSignature, expressions, (expressionValidator.ValidateFunctionParameter)));
 }
コード例 #23
0
 /// <summary>
 ///     Determines if a given <see cref="LSLFunctionSignature" /> is a duplicate definition of this function signature. <para/>
 ///     The logic behind this is a bit different than SignatureMatches(). <para/>
 ///     If the given function signature has the same name, a differing return type and both functions have no parameters;
 ///     than this function will return true
 ///     and <see cref="ILSLFunctionSignature.SignatureEquivalent" /> will not. <para/>
 ///     If the other signature is an overload that is ambiguous in all cases due to variadic parameters, this function
 ///     returns true.
 /// </summary>
 /// <remarks>
 /// </remarks>
 /// <param name="otherSignature">The other function signature to compare to</param>
 /// <returns>
 ///     True if the two signatures are duplicate definitions of each other, taking static overloading ambiguities into
 ///     account.
 /// </returns>
 public bool DefinitionIsDuplicate(ILSLFunctionSignature otherSignature)
 {
     return(LSLFunctionSignatureMatcher.DefinitionIsDuplicate(this, otherSignature));
 }
コード例 #24
0
 void ILSLSyntaxWarningListener.DeadCodeDetected(LSLSourceCodeRange location,
                                                 ILSLFunctionSignature currentFunction, ILSLDeadCodeSegment deadSegment)
 {
     _warningActionQueue.Enqueue(location.StartIndex,
                                 () => SyntaxWarningListener.DeadCodeDetected(location, currentFunction, deadSegment));
 }
コード例 #25
0
 void ILSLSyntaxErrorListener.NotAllCodePathsReturnAValue(LSLSourceCodeRange location,
                                                          ILSLFunctionSignature inFunction)
 {
     _errorActionQueue.Enqueue(location.StartIndex,
                               () => SyntaxErrorListener.NotAllCodePathsReturnAValue(location, inFunction));
 }
コード例 #26
0
 void ILSLSyntaxErrorListener.DeadCodeAfterReturnPath(LSLSourceCodeRange location,
                                                      ILSLFunctionSignature inFunction, ILSLDeadCodeSegment deadSegment)
 {
     _errorActionQueue.Enqueue(location.StartIndex,
                               () => SyntaxErrorListener.DeadCodeAfterReturnPath(location, inFunction, deadSegment));
 }
コード例 #27
0
 void ILSLSyntaxErrorListener.RedefinedFunction(LSLSourceCodeRange location,
                                                ILSLFunctionSignature previouslyDefinedSignature)
 {
     _errorActionQueue.Enqueue(location.StartIndex,
                               () => SyntaxErrorListener.RedefinedFunction(location, previouslyDefinedSignature));
 }
コード例 #28
0
 /// <summary>
 ///     Construct an <see cref="LSLFunctionCallNode" /> with an arguments list.
 ///     This represents a call to a library function, since it has no definition node.
 /// </summary>
 /// <param name="functionSignature">The signature of the library function.</param>
 /// <param name="argumentList">The list of expression arguments.</param>
 /// <exception cref="ArgumentNullException">
 ///     <paramref name="functionSignature" /> or <paramref name="argumentList" /> is
 ///     <c>null</c>.
 /// </exception>
 public LSLFunctionCallNode(ILSLFunctionSignature functionSignature, params ILSLExprNode[] argumentList)
     : this(functionSignature, new LSLExpressionListNode(argumentList))
 {
 }
コード例 #29
0
 void ILSLSyntaxErrorListener.ReturnedVoidFromNonVoidFunction(LSLSourceCodeRange location,
                                                              ILSLFunctionSignature functionSignature)
 {
     _errorActionQueue.Enqueue(location.StartIndex,
                               () => SyntaxErrorListener.ReturnedVoidFromNonVoidFunction(location, functionSignature));
 }
コード例 #30
0
        /// <summary>
        ///     Check if a given function signature can be called with the given expressions as parameters
        /// </summary>
        /// <param name="typeComparer">A function which should return true if two types match</param>
        /// <param name="functionSignature">The function signature of the functions your passing the parameter expressions to.</param>
        /// <param name="expressions">The expressions we want to test against this function signatures defined parameters.</param>
        /// <returns>
        ///     A LSLFunctionCallSignatureMatcher.MatchStatus object containing information about how the parameters matched
        ///     or did not match the call signature.
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="functionSignature"/> or <paramref name="expressions"/> or <paramref name="typeComparer"/> is <c>null</c>.</exception>
        public static LSLFunctionSignatureMatch TryMatch(ILSLFunctionSignature functionSignature,
                                                         IReadOnlyGenericArray <ILSLReadOnlyExprNode> expressions, Func <LSLParameterSignature, ILSLReadOnlyExprNode, bool> typeComparer)
        {
            if (functionSignature == null)
            {
                throw new ArgumentNullException("functionSignature");
            }
            if (expressions == null)
            {
                throw new ArgumentNullException("expressions");
            }
            if (typeComparer == null)
            {
                throw new ArgumentNullException("typeComparer");
            }


            int  parameterNumber       = 0;
            bool parameterTypeMismatch = false;

            //if we supplied to many parameters, and there is not a variadic
            //parameter at the end of the signature, then there is not a match
            if (functionSignature.HasVariadicParameter == false &&
                expressions.Count > functionSignature.ParameterCount)
            {
                return(new LSLFunctionSignatureMatch(false, true, false, -1));
            }


            //not enough parameters to fill all of the concrete (non variadic) parameters in
            //we do not have enough expressions to call this function signature
            if (expressions.Count < functionSignature.ConcreteParameterCount)
            {
                return(new LSLFunctionSignatureMatch(true, false, false, -1));
            }


            //check the types of all parameters match, including variadic parameters from the signature if they are not Void
            //if the variadic parameter is Void than anything can go in it, so it is not even checked
            for (; parameterNumber < expressions.Count; parameterNumber++)
            {
                LSLParameterSignature compareWithThisSignatureParameter;

                if (parameterNumber > (functionSignature.ParameterCount - 1))
                {
                    //If this happens it means we are in a continuation of a variadic parameter, we want to continue comparing the rest of the passed
                    //expressions to the last parameter in the function signature, IE. the variadic parameter.
                    compareWithThisSignatureParameter =
                        functionSignature.Parameters[functionSignature.ParameterCount - 1];
                }
                else
                {
                    //We have not flowed over the parameter count of the signature, so theres no danger
                    //of an out of bounds index on the parameters array in the signature.
                    compareWithThisSignatureParameter = functionSignature.Parameters[parameterNumber];
                }


                //no type check required, the variadic parameter allows everything in because its type is Void, anything you put in is a match
                //from here on out.  So its safe to return from the loop now and stop checking parameters.
                if (compareWithThisSignatureParameter.Variadic && compareWithThisSignatureParameter.Type == LSLType.Void)
                {
                    break;
                }

                //use the type comparer to check for a match, there might be some special case like string literals
                //being passed into a Key parameter, this behavior is delegated for better re-usability
                if (typeComparer(compareWithThisSignatureParameter, expressions[parameterNumber]))
                {
                    continue;
                }

                //the expression could not be passed into the parameter due to a type mismatch, we are done checking the parameters
                //because we know for a fact the expressions given do not match this call signature
                parameterTypeMismatch = true;
                break;
            }


            //if there was a parameter mismatch, the last checked parameter index is the index at which the mismatch occurred
            var badParameterIndex = parameterTypeMismatch ? parameterNumber : -1;

            //we had an allowable amount of parameters, but there was a type mismatch somewhere
            return(new LSLFunctionSignatureMatch(false, false, parameterTypeMismatch, badParameterIndex));
        }