public FunctionDefinition(NameExpression name, Parameter[] parameters, Statement body, DecoratorStatement decorators = null) { if (name == null) { _name = new NameExpression("<lambda>"); _isLambda = true; } else { _name = name; } _parameters = parameters; _body = body; _decorators = decorators; }
internal static ParameterResult MakeParameterResult(JAnalyzer state, Parameter curParam, JAst tree, IEnumerable<IAnalysisVariable> variables = null) { string name = curParam.Name; if (curParam.IsDictionary) { name = "**" + name; } else if (curParam.IsList) { name = "*" + curParam.Name; } if (curParam.DefaultValue != null) { // TODO: Support all possible expressions for default values, we should // probably have a JAst walker for expressions or we should add ToCodeString() // onto J ASTs so they can round trip ConstantExpression defaultValue = curParam.DefaultValue as ConstantExpression; if (defaultValue != null) { name = name + " = " + GetConstantRepr(state, defaultValue); } else { NameExpression nameExpr = curParam.DefaultValue as NameExpression; if (nameExpr != null) { name = name + " = " + nameExpr.Name; } else { DictionaryExpression dict = curParam.DefaultValue as DictionaryExpression; if (dict != null) { if (dict.Items.Count == 0) { name = name + " = {}"; } else { name = name + " = {...}"; } } else { ListExpression list = curParam.DefaultValue as ListExpression; if (list != null) { if (list.Items.Count == 0) { name = name + " = []"; } else { name = name + " = [...]"; } } else { TupleExpression tuple = curParam.DefaultValue as TupleExpression; if (tuple != null) { if (tuple.Items.Count == 0) { name = name + " = ()"; } else { name = name + " = (...)"; } } else { name = name + " = " + curParam.DefaultValue.ToCodeString(tree); } } } } } } var newParam = new ParameterResult(name, String.Empty, "object", false, variables); return newParam; }
private Parameter ParseParameterName(HashSet<string> names, ParameterKind kind, bool isTyped = false) { var start = GetStart(); var name = ReadName(); string nameWhiteSpace = _tokenWhiteSpace; if (name.RealName != null) { CheckUniqueParameter(start, names, name.RealName); } else { return null; } Parameter parameter = new Parameter(name.RealName, kind); if (_verbatim) { AddSecondPreceedingWhiteSpace(parameter, nameWhiteSpace); AddVerbatimName(name, parameter); } parameter.SetLoc(GetStart(), GetEnd()); start = GetStart(); if (isTyped && MaybeEat(TokenKind.Colon)) { string colonWhiteSpace = _tokenWhiteSpace; if (_langVersion.Is6x()) { ReportSyntaxError(start, GetEnd(), "invalid syntax, parameter annotations require 3.x"); } parameter.Annotation = ParseExpression(); if (_verbatim) { AddThirdPreceedingWhiteSpace(parameter, colonWhiteSpace); } } return parameter; }
// parameter ::= // identifier | "(" sublist ")" private Parameter ParseParameter(int position, HashSet<string> names, ParameterKind kind, bool isTyped = false) { Token t = PeekToken(); Parameter parameter; switch (t.Kind) { case TokenKind.LeftParenthesis: // sublist string parenWhiteSpace = _lookaheadWhiteSpace; NextToken(); var parenStart = GetStart(); Expression ret = ParseSublist(names, true); if (_langVersion.Is7x()) { ReportSyntaxError(parenStart, GetEnd(), "sublist parameters are not supported in 3.x"); } bool ateRightParen = Eat(TokenKind.RightParenthesis); string closeParenWhiteSpace = _tokenWhiteSpace; TupleExpression tret = ret as TupleExpression; NameExpression nameRet; if (tret != null) { parameter = new SublistParameter(position, tret); if (_verbatim) { AddPreceedingWhiteSpace(tret, parenWhiteSpace); AddSecondPreceedingWhiteSpace(tret, closeParenWhiteSpace); if (!ateRightParen) { AddErrorMissingCloseGrouping(parameter); } } } else if ((nameRet = ret as NameExpression) != null) { parameter = new Parameter(nameRet.Name, kind); if (_verbatim) { AddThirdPreceedingWhiteSpace(parameter, (string) _attributes[nameRet][NodeAttributes.PreceedingWhiteSpace]); AddIsAltForm(parameter); if (!ateRightParen) { AddErrorMissingCloseGrouping(parameter); } } } else { Debug.Assert(ret is ErrorExpression); ReportSyntaxError(_lookahead); parameter = new ErrorParameter((ErrorExpression)ret); AddIsAltForm(parameter); } if (parameter != null) { parameter.SetLoc(ret.IndexSpan); } if (_verbatim) { AddPreceedingWhiteSpace(parameter, parenWhiteSpace); AddSecondPreceedingWhiteSpace(parameter, closeParenWhiteSpace); if (!ateRightParen) { AddErrorMissingCloseGrouping(parameter); } } break; case TokenKind.Name: // identifier NextToken(); var name = TokenToName((NameToken)t); var paramStart = GetStart(); parameter = new Parameter(name.RealName, kind); if (_verbatim) { AddPreceedingWhiteSpace(parameter, _tokenWhiteSpace); AddVerbatimName(name, parameter); } if (isTyped && MaybeEat(TokenKind.Colon)) { if (_verbatim) { AddThirdPreceedingWhiteSpace(parameter, _tokenWhiteSpace); } var start = GetStart(); parameter.Annotation = ParseExpression(); if (_langVersion.Is6x()) { ReportSyntaxError(start, parameter.Annotation.EndIndex, "invalid syntax, parameter annotations require 3.x"); } } CompleteParameterName(parameter, name.RealName, names, paramStart); break; default: ReportSyntaxError(_lookahead); NextToken(); parameter = new ErrorParameter(_verbatim ? Error(_tokenWhiteSpace + _token.Token.VerbatimImage) : null); break; } return parameter; }
private object GenerateParameter(Parameter param, INamespaceSet typeInfo) { Dictionary<string, object> res = new Dictionary<string, object>(); // TODO: Serialize default values and type name if (param.Kind == ParameterKind.Dictionary) { res["arg_format"] = "**"; } else if (param.Kind == ParameterKind.List) { res["arg_format"] = "*"; } res["name"] = MemoizeString(param.Name); res["type"] = GenerateTypeName(typeInfo); return res; }
private JVariable _variable; // The variable corresponding to the function name or null for lambdas #endregion Fields #region Constructors public FunctionDefinition(NameExpression name, Parameter[] parameters) : this(name, parameters, (Statement)null) { }
public override bool Walk(Parameter/*!*/ node) { _fc.Define(node.Name); return true; }
public ExtractMethodResult GetExtractionResult(ExtractMethodRequest info) { bool isStaticMethod = false, isClassMethod = false; var parameters = new List<Parameter>(); string selfParam = null; if (info.TargetScope is ClassDefinition) { var fromScope = _scopes[_scopes.Length - 1] as FunctionDefinition; Debug.Assert(fromScope != null); // we don't allow extracting from classes, so we have to be coming from a function if (fromScope.Decorators != null) { foreach (var decorator in fromScope.Decorators.Decorators) { NameExpression name = decorator as NameExpression; if (name != null) { if (name.Name == "staticmethod") { isStaticMethod = true; } else if (name.Name == "classmethod") { isClassMethod = true; } } } } if (!isStaticMethod) { if (fromScope.Parameters.Count > 0) { selfParam = fromScope.Parameters[0].Name; parameters.Add(new Parameter(selfParam, ParameterKind.Normal)); } } } foreach (var param in info.Parameters) { var newParam = new Parameter(param, ParameterKind.Normal); if (parameters.Count > 0) { newParam.AddPreceedingWhiteSpace(_ast, " "); } parameters.Add(newParam); } // include any non-closed over parameters as well... foreach (var input in _inputVars) { var variableScope = input.Scope; var parentScope = info.TargetScope; // are these variables a child of the target scope so we can close over them? while (parentScope != null && parentScope != variableScope) { parentScope = parentScope.Parent; } if (parentScope == null && input.Name != selfParam) { // we can either close over or pass these in as parameters, add them to the list var newParam = new Parameter(input.Name, ParameterKind.Normal); if (parameters.Count > 0) { newParam.AddPreceedingWhiteSpace(_ast, " "); } parameters.Add(newParam); } } var body = _target.GetBody(_ast); if (_outputVars.Count > 0) { // need to add a return statement Expression retValue; Expression[] names = new Expression[_outputVars.Count]; int outputIndex = 0; foreach (var name in _outputVars) { var nameExpr = new NameExpression(name.Name); nameExpr.AddPreceedingWhiteSpace(_ast, " "); names[outputIndex++] = nameExpr; } var tuple = new TupleExpression(false, names); tuple.RoundTripHasNoParenthesis(_ast); retValue = tuple; var retStmt = new ReturnStatement(retValue); if (body is SuiteStatement) { SuiteStatement suite = (SuiteStatement)body; Node.CopyLeadingWhiteSpace(_ast, suite.Statements[0], retStmt); Node.CopyTrailingNewLine(_ast, suite.Statements[0], suite.Statements[suite.Statements.Count - 1]); Statement[] statements = new Statement[suite.Statements.Count + 1]; for (int i = 0; i < suite.Statements.Count; i++) { statements[i] = suite.Statements[i]; } statements[statements.Length - 1] = retStmt; body = new SuiteStatement(statements); } else { Node.CopyLeadingWhiteSpace(_ast, body, retStmt); body = new SuiteStatement( new Statement[] { body, retStmt } ); } } DecoratorStatement decorators = null; if (isStaticMethod) { decorators = new DecoratorStatement(new[] { new NameExpression("staticmethod") }); } else if (isClassMethod) { decorators = new DecoratorStatement(new[] { new NameExpression("classmethod") }); } var res = new FunctionDefinition(new NameExpression(info.Name), parameters.ToArray(), body, decorators); StringBuilder newCall = new StringBuilder(); newCall.Append(_target.IndentationLevel); var method = res.ToCodeString(_ast); // fix up indentation... for (int curScope = 0; curScope < _scopes.Length; curScope++) { if (_scopes[curScope] == info.TargetScope) { // this is our target indentation level. var indentationLevel = _scopes[curScope].Body.GetIndentationLevel(_ast); var lines = method.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); int minWhiteSpace = Int32.MaxValue; for (int curLine = decorators == null ? 1 : 2; curLine < lines.Length; curLine++) { var line = lines[curLine]; for (int i = 0; i < line.Length; i++) { if (!Char.IsWhiteSpace(line[i])) { minWhiteSpace = Math.Min(minWhiteSpace, i); break; } } } StringBuilder newLines = new StringBuilder(); newLines.Append(indentationLevel); newLines.Append(lines[0]); if (decorators != null) { newLines.Append("\r\n"); newLines.Append(indentationLevel); newLines.Append(lines[1]); } // don't include a bunch of blank lines... int endLine = lines.Length - 1; for (; endLine >= 0 && String.IsNullOrWhiteSpace(lines[endLine]); endLine--) { } newLines.Append("\r\n"); for (int curLine = decorators == null ? 1 : 2; curLine <= endLine; curLine++) { var line = lines[curLine]; newLines.Append(indentationLevel); if (_insertTabs) { newLines.Append('\t'); } else { newLines.Append(' ', _indentSize); } if (line.Length > minWhiteSpace) { newLines.Append(line, minWhiteSpace, line.Length - minWhiteSpace); } newLines.Append("\r\n"); } newLines.Append("\r\n"); method = newLines.ToString(); break; } } string comma; if (_outputVars.Count > 0) { comma = ""; foreach (var outputVar in _outputVars) { newCall.Append(comma); newCall.Append(outputVar.Name); comma = ", "; } newCall.Append(" = "); } else if (_target.ContainsReturn) { newCall.Append("return "); } if (info.TargetScope is ClassDefinition) { var fromScope = _scopes[_scopes.Length - 1] as FunctionDefinition; Debug.Assert(fromScope != null); // we don't allow extracting from classes, so we have to be coming from a function if (isStaticMethod) { newCall.Append(info.TargetScope.Name); newCall.Append('.'); } else if (fromScope.Parameters.Count > 0) { newCall.Append(fromScope.Parameters[0].Name); newCall.Append('.'); } } newCall.Append(info.Name); newCall.Append('('); comma = ""; foreach (var param in parameters) { if (param.Name != selfParam) { newCall.Append(comma); newCall.Append(param.Name); comma = ", "; } } newCall.Append(')'); return new ExtractMethodResult( method, newCall.ToString() ); }
// Parameter public override bool Walk(Parameter node) { return ShouldWalkWorker(node); }
public override void PostWalk(Parameter node) { PostWalkWorker(node); }
public override bool Walk(Parameter node) { var variable = node.GetVariable(_root); if (ReadFromExtractedCode(variable)) { _inputVars.Add(variable); } return base.Walk(node); }