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>()); }
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); }
public static FunctionParameterNode GetParameterDefinition(this FunctionCallExpressionNode callExpression, int parameterIndex) { var functionDefinition = callExpression.GetDefinition(); if (functionDefinition == null) { return(null); } return(functionDefinition.Header.Parameters.ElementAtOrDefault(parameterIndex)); }