예제 #1
0
        public static IEnumerable <PapyrusSymbol> GetKnownParameterValueSymbols(this FunctionCallExpressionNode functionCallExpression, int parameterIndex, out bool valuesAreValidExclusively)
        {
            valuesAreValidExclusively = false;

            var definedFunction     = functionCallExpression.GetDefinition();
            var parameterDefinition = functionCallExpression.GetParameterDefinition(parameterIndex);

#if FALLOUT4
            if (parameterDefinition != null)
            {
                var parameterTypeName = parameterDefinition.TypeIdentifier.Text;

                if (parameterTypeName.CaseInsensitiveEquals("CustomEventName"))
                {
                    valuesAreValidExclusively = true;
                    return(GetKnownEventParameterSymbols <CustomEventSymbol>(functionCallExpression, parameterIndex));
                }

                if (parameterTypeName.CaseInsensitiveEquals("ScriptEventName"))
                {
                    valuesAreValidExclusively = true;
                    return(GetKnownEventParameterSymbols <EventSymbol>(functionCallExpression, parameterIndex));
                }

                var functionName = definedFunction.Header.Identifier.Text;
                if (functionName.CaseInsensitiveEquals("FindStruct") || functionName.CaseInsensitiveEquals("RFindStruct"))
                {
                    if (parameterDefinition.Identifier.Text.CaseInsensitiveEquals("asVarName"))
                    {
                        valuesAreValidExclusively = true;

                        var definedFunctionScriptSymbol = definedFunction.Symbol.Script;
                        var elementTypeId = definedFunctionScriptSymbol.SyntheticArrayType?.ElementType;
                        if (elementTypeId.HasValue)
                        {
                            if (functionCallExpression.GetTypeChecker().GetTypeForObjectId(elementTypeId.Value) is StructType elementType)
                            {
                                return(elementType.Symbol.Children);
                            }
                        }

                        return(Enumerable.Empty <PapyrusSymbol>());
                    }
                }
            }
#endif

            if (definedFunction.Symbol.Name.CaseInsensitiveEquals("GotoState"))
            {
                var expressionForScriptType = functionCallExpression.GetMemberAccessExpression()?.BaseExpression;
                var scriptType = expressionForScriptType?.GetTypeOfExpression() as ScriptType ?? functionCallExpression.Script.Symbol.GetPapyrusType() as ScriptType;

                return(scriptType.Symbol.GetExtendedScriptChain(true).
                       SelectMany(scriptSymbol => scriptSymbol.Children.OfType <StateSymbol>()).
                       DistinctBy(s => s.Name.ToLower()).ToArray());
            }

            return(Enumerable.Empty <PapyrusSymbol>());
        }
예제 #2
0
        public static int GetFunctionParameterIndexAtPosition(this FunctionCallExpressionNode functionCallExpression, Position position)
        {
            var intersectingParameterIndex = 0;

            // Here, we're making the parameter node ranges contiguous
            var parameterRanges = new List <Range>();

            for (var i = 0; i < functionCallExpression.Parameters.Count; i++)
            {
                var range = functionCallExpression.Parameters[i].Range;
                if (i > 0)
                {
                    var previousParameterEnd = functionCallExpression.Parameters[i - 1].Range.End;

                    range = new Range()
                    {
                        Start = new Position()
                        {
                            Line      = previousParameterEnd.Line,
                            Character = previousParameterEnd.Character + 1
                        },
                        End = new Position()
                        {
                            Line      = range.End.Line,
                            Character = range.End.Character + 1
                        }
                    };
                }

                parameterRanges.Add(range);
            }

            var intersectingRange = parameterRanges.LastOrDefault(r => position >= r.Start);

            intersectingParameterIndex = parameterRanges.IndexOf(intersectingRange);

            // If we're intersecting a named call parameter, we want to adjust the index to match the actual signature index.
            var intersectingCallParameter = functionCallExpression.Parameters.ElementAtOrDefault(intersectingParameterIndex);

            if (intersectingCallParameter != null)
            {
                if (intersectingCallParameter.Identifier != null)
                {
                    var parameterDefinition = intersectingCallParameter.GetParameterDefinition();
                    return(functionCallExpression.GetDefinition().Header.Parameters.IndexOf(parameterDefinition));
                }
            }

            if (intersectingParameterIndex == -1)
            {
                intersectingParameterIndex = 0;
            }

            return(intersectingParameterIndex);
        }
예제 #3
0
        public static FunctionParameterNode GetParameterDefinition(this FunctionCallExpressionNode callExpression, int parameterIndex)
        {
            var functionDefinition = callExpression.GetDefinition();

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

            return(functionDefinition.Header.Parameters.ElementAtOrDefault(parameterIndex));
        }