/// <summary> /// Returns the overloads for a normal .NET type /// </summary> private IPythonFunction GetClrOverloads() { Type clrType = ClrModule.GetClrType(Value); // just a normal .NET type... var ctors = clrType.GetConstructors(BindingFlags.Public | BindingFlags.CreateInstance | BindingFlags.Instance); if (ctors.Length > 0) { return(new IronPythonConstructorFunction(Interpreter, ctors, this)); } return(null); /* * var overloads = new OverloadResult[ctors.Length]; * for (int i = 0; i < ctors.Length; i++) { * // TODO: Docs, python type name * var parameters = ctors[i].GetParameters(); * * bool hasContext = parameters.Length > 0 && parameters[0].ParameterType == typeof(CodeContext); * * var paramResult = new ParameterResult[hasContext ? parameters.Length - 1 : parameters.Length]; * * for (int j = 0; j < paramResult.Length; j++) { * var curParam = parameters[j + (hasContext ? 1 : 0)]; * // TODO: Docs * paramResult[j] = BuiltinFunctionOverloadResult.GetParameterResultFromParameterInfo(curParam); * } * overloads[i] = new SimpleOverloadResult(paramResult, Value.Name, ""); * } * * return overloads;*/ }
public IPythonFunction GetConstructors() { var clrType = ClrModule.GetClrType(Value); var newMethods = clrType.GetMember("__new__", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static); if (!IsPythonType) { var initMethods = clrType.GetMember("__init__", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance); if (newMethods.Length == 0 && initMethods.Length == 0) { return(GetClrOverloads()); } } else if (clrType == typeof(object)) { return(GetClrOverloads()); } return(null);/* * object ctor; * if (!ProjectState.TryGetMember(Value, "__new__", out ctor)) { * ctor = null; * } * var func = ctor as IBuiltinFunction; * if (func == null) { * return new OverloadResult[0]; * }*/ }
/// <summary> /// Returns the overloads for a normal .NET type /// </summary> private OverloadResult[] GetClrOverloads() { Type clrType = ClrModule.GetClrType(_type); // just a normal .NET type... var ctors = clrType.GetConstructors(BindingFlags.Public | BindingFlags.CreateInstance | BindingFlags.Instance); var overloads = new OverloadResult[ctors.Length]; for (int i = 0; i < ctors.Length; i++) { // TODO: Docs, python type name var parameters = ctors[i].GetParameters(); bool hasContext = parameters.Length > 0 && parameters[0].ParameterType == typeof(CodeContext); var paramResult = new ParameterResult[hasContext ? parameters.Length - 1 : parameters.Length]; for (int j = 0; j < paramResult.Length; j++) { var curParam = parameters[j + (hasContext ? 1 : 0)]; // TODO: Docs paramResult[j] = BuiltinFunctionOverloadResult.GetParameterResultFromParameterInfo(curParam); } overloads[i] = new SimpleOverloadResult(paramResult, PythonType.Get__name__(_type), ""); } return(overloads); }
/// <summary> /// Generates completion data for the specified text, while import the given types into the /// scope and discovering variable assignments. /// </summary> /// <param name="line">The code to parse</param> /// <returns>Return a list of IronPythonCompletionData </returns> public ICompletionData[] GetCompletionData(string line) { var items = new List <IronPythonCompletionData>(); this.UpdateImportedTypes(line); this.UpdateVariableTypes(line); // this is where hindley-milner could come into play string name = GetName(line); if (!String.IsNullOrEmpty(name)) { try { AutocompletionInProgress = true; // is it a CLR type? var type = TryGetType(name); if (type != null) { items = EnumerateMembers(type, name); } // it's a variable? else if (this.VariableTypes.ContainsKey(name)) { items = EnumerateMembers(this.VariableTypes[name], name); } // is it a namespace or python type? else { var mem = LookupMember(name); if (mem is NamespaceTracker) { items = EnumerateMembers(mem as NamespaceTracker, name); } else if (mem is PythonModule) { items = EnumerateMembers(mem as PythonModule, name); } else if (mem is PythonType) { // shows static and instance methods in just the same way :( var value = ClrModule.GetClrType(mem as PythonType); if (value != null) { items = EnumerateMembers(value, name); } } } } catch { //Dynamo.this.logger.Log("EXCEPTION: GETTING COMPLETION DATA"); } AutocompletionInProgress = false; } return(items.ToArray()); }
/// <summary> /// Find all variable assignments in the source code and attempt to discover their type /// </summary> /// <param name="code">The code from whih to get the assignments</param> /// <returns>A dictionary matching the name of the variable to a tuple of typeName, character at which the assignment was found, and the CLR type</returns> public Dictionary <string, Tuple <string, int, Type> > FindAllVariables(string code) { // regex to collection var variables = new Dictionary <string, Tuple <string, int, Type> >(); var variableStatements = Regex.Matches(code, variableName + spacesOrNone + equals + spacesOrNone + @"(.*)", RegexOptions.Multiline); for (var i = 0; i < variableStatements.Count; i++) { var name = variableStatements[i].Groups[1].Value.Trim(); var typeString = variableStatements[i].Groups[6].Value.Trim(); // type var currentIndex = variableStatements[i].Index; // check if matches typename(blabla) - in this case its a type we need to look up var typeStringMatches = Regex.Matches(typeString, @"^(.*)\(.*\)$", RegexOptions.Singleline); if (typeStringMatches.Count > 0) { typeString = typeStringMatches[0].Groups[1].Value.Trim(); var typeInScope = this.LookupMember(typeString); if (typeInScope is PythonType) // dictionary, enum, etc { var type = ClrModule.GetClrType(typeInScope as PythonType); //// if we already saw this var if (variables.ContainsKey(name)) { var varInfo = variables[name]; if (currentIndex > varInfo.Item2) { variables[name] = new Tuple <string, int, Type>(typeString, currentIndex, type); } } else // we've never seen it, add the type { variables.Add(name, new Tuple <string, int, Type>(typeString, currentIndex, type)); } } } else // match default types (numbers, dicts, arrays, strings) { foreach (var pair in RegexToType) { var matches = Regex.Matches(typeString, "^" + pair.Key + "$", RegexOptions.Singleline); if (matches.Count > 0) { // if we already saw this var if (variables.ContainsKey(name)) { var varInfo = variables[name]; if (currentIndex > varInfo.Item2) { variables[name] = new Tuple <string, int, Type>(typeString, currentIndex, pair.Value); } } else // we've never seen it, add the type { variables.Add(name, new Tuple <string, int, Type>(typeString, currentIndex, pair.Value)); } break; } } } } return(variables); }
/// <summary> /// Generate completion data for the specified text, while import the given types into the /// scope and discovering variable assignments. /// </summary> /// <param name="code">The code to parse</param> /// <param name="expand">Determines if the entire namespace should be used</param> /// <returns>Return a list of IExternalCodeCompletionData </returns> public IExternalCodeCompletionData[] GetCompletionData(string code, bool expand = false) { IEnumerable <IronPythonCodeCompletionDataCore> items = new List <IronPythonCodeCompletionDataCore>(); if (code.Contains("\"\"\"")) { code = StripDocStrings(code); } UpdateImportedTypes(code); UpdateVariableTypes(code); // Possibly use hindley-milner in the future // If expand param is true use the entire namespace from the line of code // Else just return the last name of the namespace string name = expand ? GetLastNameSpace(code) : GetLastName(code); if (!String.IsNullOrEmpty(name)) { try { // Attempt to get type using naming Type type = expand ? TryGetTypeFromFullName(name) : TryGetType(name); // CLR type if (type != null) { items = EnumerateMembers(type, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); } // Variable type else if (VariableTypes.TryGetValue(name, out type)) { items = EnumerateMembers(type, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); } else { var mem = LookupMember(name); var namespaceTracker = mem as NamespaceTracker; // Namespace type if (namespaceTracker != null) { items = EnumerateMembersFromTracker(namespaceTracker, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); } else { var pythonModule = mem as PythonModule; // Python Module type if (pythonModule != null) { items = EnumerateMembers(pythonModule, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); } // Python type else if (mem is PythonType) { // Shows static and instance methods in the same way :( var value = ClrModule.GetClrType(mem as PythonType); if (value != null) { items = EnumerateMembers(value, name).Select(x => new IronPythonCodeCompletionDataCore(x.Item1, x.Item2, x.Item3, x.Item4, this)); } } } } } catch (Exception ex) { Log(ex.ToString()); } } // If unable to find matching results and expand was set to false, // try again using the full namespace (set expand to true) if (!items.Any() && !expand) { return(GetCompletionData(code, true)); } return(items.ToArray()); }