public override void Visit(ImportSyntax pNode) { if (!_importPath.Contains(pNode.Path)) { _importPath.Add(pNode.Path); var path = System.IO.Path.GetFullPath(System.IO.Path.Combine(_path, pNode.Path + ".dll")); Assembly asm = null; try { asm = Assembly.LoadFile(path); } catch (Exception) { Compiler.ReportError(CompilerErrorType.InvalidImport, pNode, pNode.Path); return; } try { System.IO.File.Copy(path, System.IO.Path.Combine(_path, System.IO.Path.GetFileName(path)), true); } catch (Exception) { Compiler.ReportError("Unable to copy import to local directory"); } //Import all types from the import //TODO move this to struct definition thing? foreach (var t in asm.GetTypes()) { if (t.IsValueType && t.IsPublic) { string prefix = ""; var attr = t.GetCustomAttributes <Emitting.TypePrefixAttribute>().SingleOrDefault(); //All exported types must have a TypePrefixAttribute in order to be imported if (attr != null) { // //Create type // prefix = attr.Prefix; //Get any generic type parameters of the type List <string> typeParameters = new List <string>(); if (t.IsGenericType) { var ga = t.GetGenericArguments(); for (int i = 0; i < ga.Length; i++) { typeParameters.Add(ga[i].Name); } } var st = SmallType.RegisterType(pNode.Alias, prefix, true, typeParameters); st.SetSystemType(t); foreach (var f in t.GetFields()) { SmallType fieldType = null; if (f.FieldType.IsGenericParameter) { //If it's a generic type parameter, use the generic type foreach (var s in st.GenericTypeParameters) { if (s.Name.Equals(f.FieldType.Name, StringComparison.OrdinalIgnoreCase)) { fieldType = s; } } } else { fieldType = SmallType.FromSystemType(f.FieldType); } typeParameters.Clear(); //Get field type parameters if (f.FieldType.ContainsGenericParameters) { var typeArguments = t.GetGenericArguments(); foreach (var tp in typeArguments) { if (tp.IsGenericParameter) { typeParameters.Add(tp.Name); } } } st.AddField(f.Name, typeParameters, fieldType); } //Check if we have an initializer function var m = t.GetMethod("Initialize"); if (m != null) { var ii = new InitializerInfo(null); ii.SetMethod(m); st.SetInitializer(ii); } } } } foreach (var t in asm.GetTypes()) { foreach (var m in t.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)) { var p = m.GetParameters(); MethodDefinition.Parameter[] parameters = new MethodDefinition.Parameter[p.Length]; for (int i = 0; i < p.Length; i++) { parameters[i] = new MethodDefinition.Parameter(SmallType.FromSystemType(p[i].ParameterType), p[i].Name, p[i].ParameterType.IsByRef); } SmallType[] returnType; if (m.ReturnType.IsConstructedGenericType) { var types = m.ReturnType.GetGenericArguments(); returnType = new SmallType[types.Length]; for (int i = 0; i < types.Length; i++) { returnType[i] = SmallType.FromSystemType(types[i]); } } else if (m.ReturnType.IsGenericParameter) { returnType = new SmallType[] { SmallType.CreateGenericParameter(m.ReturnType.Name) }; } else if (m.ReturnType != typeof(void)) { returnType = new SmallType[] { SmallType.FromSystemType(m.ReturnType) } } ; else { returnType = new SmallType[0]; } List <SmallType> typeHints = new List <SmallType>(); if (m.IsGenericMethodDefinition) { var typeParameters = m.GetGenericArguments(); foreach (var tp in typeParameters) { if (tp.IsGenericParameter) { typeHints.Add(SmallType.CreateGenericParameter(tp.Name)); } } } MethodDefinition md = null; if (returnType.Length == 1 && parameters.Length == 1 && m.Name == MetadataCache.CastFunction(parameters[0].Type, returnType[0])) { md = MetadataCache.AddImportedCast(pNode.Alias, parameters[0].Type, parameters[0].Name, returnType[0]); } else { md = MetadataCache.AddImportedMethod(pNode.Alias, m.Name, parameters, returnType, typeHints); } md.SetExternMethod(m); } } } if (MetadataCache.ImportedNamespaces().Contains(pNode.Alias)) { Compiler.ReportError(CompilerErrorType.DuplicateImportAlias, pNode, pNode.Alias); } else { MetadataCache.AddNamespace(pNode.Alias); } }
/// <summary> /// Initializes a new instance of the <see cref="ImportSymbol"/> class. /// </summary> /// <param name="name">The import name.</param> /// <param name="declaration">The declaration.</param> public ImportSymbol(string name, ImportSyntax declaration) : base(name) { Declaration = declaration; }