public static void ImportExtensionMethodsIntoPackage(Package package, Type type) { var isbuiltin = type.Assembly == Assembly.GetExecutingAssembly(); var extendedType = (Type)package.Dict["T"].CheckedValue; var restrictedImport = type.GetCustomAttributes(typeof(RestrictedImportAttribute), true).Length != 0; var names = type.GetMethods(ImportBindingFlags).Select(x => x.Name).Distinct().ToArray(); foreach (var name in names) { var methods = type.GetMember(name, ImportBindingFlags) .Where(x => x is MethodInfo) .Select(x => (MethodInfo)ResolveGenericMethod((MethodInfo)x)) .Where(x => ExtendsType(x, extendedType)) .ToList(); if (methods.Count == 0) { continue; } var importable = !restrictedImport || methods[0].GetCustomAttributes(typeof(LispAttribute), true).Length != 0; if (!importable) { continue; } var sym = package.Create(name.LispName(), ispublic: true); var builtin = sym.Value as ImportedFunction; if (builtin == null) { sym.FunctionValue = builtin = new ImportedFunction(name, type); } if (isbuiltin) { // Designed to go before other methods. methods.AddRange(builtin.BuiltinExtensionMembers); builtin.BuiltinExtensionMembers = methods.Distinct().ToArray(); } else { // todo: change order // Goes after other methods as in c#. methods.AddRange(builtin.ExternalExtensionMembers); builtin.ExternalExtensionMembers = methods.Distinct().ToArray(); } } }
public static void ImportIntoPackage(Package package, Type type) { AddPackageByType(type, package); var restrictedImport = type.GetCustomAttributes(typeof(RestrictedImportAttribute), true).Length != 0; package.ImportedType = type; package.RestrictedImport = restrictedImport; var sym = package.Create("T", ispublic: true); sym.ConstantValue = type; sym.Documentation = string.Format("The .NET type <{0}> imported in this package.", type); ImportMembers(package); }
public static bool ImportMembers(MemberInfo[] members, Package package) { if (members.Length == 0) { return(false); } var member = members[0]; var importable = !package.RestrictedImport || member.GetCustomAttributes(typeof(LispAttribute), true).Length != 0; if (!importable) { return(false); } var name = member.Name; var ucName = name.LispName().ToUpper(); var lcName = name.LispName(); if (member is FieldInfo) { var field = member as FieldInfo; if (field.IsLiteral || (field.IsStatic && field.IsInitOnly)) { var sym = package.Create(ucName, ispublic: true); sym.ConstantValue = field.GetValue(null); } return(true); } if (member is EventInfo) { var sym = package.Create(lcName, ispublic: true); sym.ConstantValue = member; return(true); } if (member is ConstructorInfo) { var builtin = new ImportedConstructor(members.Cast <ConstructorInfo>().ToArray()); var sym = package.Create("new", ispublic: true); sym.FunctionValue = builtin; return(true); } if (member is MethodInfo) { var sym = package.Create(lcName, ispublic: true); var builtin = new ImportedFunction(name, member.DeclaringType, members.Cast <MethodInfo>().ToArray(), false); sym.FunctionValue = builtin; return(true); } if (member is PropertyInfo) { var properties = members.Cast <PropertyInfo>().ToArray(); var getters = properties.Select(x => x.GetGetMethod()).Where(x => x != null).ToArray(); var setters = properties.Select(x => x.GetSetMethod()).Where(x => x != null).ToArray(); if (getters.Length != 0) { var sym = package.Create(lcName, ispublic: true); var builtin = new ImportedFunction(name, member.DeclaringType, getters, false); sym.FunctionValue = builtin; } if (setters.Length != 0) { // create getter symbol for setf/setq package.Create(lcName, ispublic: true); // use set-xxx var sym = package.Create("set-" + lcName, ispublic: true); var builtin = new ImportedFunction(name, member.DeclaringType, setters, false); sym.FunctionValue = builtin; } return(true); } return(false); }