using System.Runtime.CompilerServices;
using System.Linq;
using System.Collections.Generic;
+using System.IO;
#if STATIC
using MetaType = IKVM.Reflection.Type;
compiled_types = new Dictionary<MetaType, TypeSpec> (40, ReferenceEquality<MetaType>.Default);
assembly_2_definition = new Dictionary<Assembly, IAssemblyDefinition> (ReferenceEquality<Assembly>.Default);
IgnorePrivateMembers = true;
+ IgnoreCompilerGeneratedField = true;
}
#region Properties
public bool IgnorePrivateMembers { get; set; }
+ public bool IgnoreCompilerGeneratedField { get; set; }
+
#endregion
public abstract void AddCompiledType (TypeBuilder builder, TypeSpec spec);
break;
default:
// Ignore private fields (even for error reporting) to not require extra dependencies
- if ((IgnorePrivateMembers && !declaringType.IsStruct) ||
- HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "CompilerGeneratedAttribute", CompilerServicesNamespace))
+ if (IgnorePrivateMembers && !declaringType.IsStruct)
+ return null;
+
+ if (IgnoreCompilerGeneratedField && HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "CompilerGeneratedAttribute", CompilerServicesNamespace))
return null;
mod = Modifiers.PRIVATE;
TypeSpec field_type;
try {
- field_type = ImportType (fi.FieldType, new DynamicTypeReader (fi));
+ field_type = ImportType (fi.FieldType, new DynamicTypeReader (fi), declaringType);
//
// Private field has private type which is not fixed buffer
if (add.Modifiers != remove.Modifiers)
throw new NotImplementedException ("Different accessor modifiers " + ei.Name);
- var event_type = ImportType (ei.EventHandlerType, new DynamicTypeReader (ei));
+ var event_type = ImportType (ei.EventHandlerType, new DynamicTypeReader (ei), declaringType);
var definition = new ImportedMemberDefinition (ei, event_type, this);
return new EventSpec (declaringType, definition, event_type, add.Modifiers, add, remove);
}
if (type.HasElementType) {
var element = type.GetElementType ();
++dtype.Position;
- spec = ImportType (element, dtype);
+ spec = ImportType (element, dtype, null);
if (!type.IsArray) {
throw new NotImplementedException ("Unknown element type " + type.ToString ());
// }
//
if (!IsMissingType (type) && type.IsGenericTypeDefinition) {
- var start_pos = spec.DeclaringType == null ? 0 : spec.DeclaringType.MemberDefinition.TypeParametersCount;
+ var start_pos = GetDeclaringTypesTypeParametersCount (spec);
var targs = CreateGenericArguments (start_pos, type.GetGenericArguments (), dtype);
spec = spec.MakeGenericType (module, targs);
}
return tspec;
}
+ static int GetDeclaringTypesTypeParametersCount (TypeSpec spec)
+ {
+ int total = 0;
+ while (spec.DeclaringType != null) {
+ total += spec.DeclaringType.MemberDefinition.TypeParametersCount;
+ spec = spec.DeclaringType;
+ }
+
+ return total;
+ }
+
public MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType)
{
Modifiers mod = ReadMethodModifiers (mb, declaringType);
kind = MemberKind.Constructor;
returnType = module.Compiler.BuiltinTypes.Void;
} else {
+ var mi = (MethodInfo)mb;
+ returnType = ImportType (mi.ReturnType, new DynamicTypeReader (mi.ReturnParameter), declaringType);
+
//
// Detect operators and destructors
//
kind = MemberKind.Operator;
}
}
- } else if (parameters.IsEmpty && name == Destructor.MetadataName) {
+ } else if (parameters.IsEmpty && name == Destructor.MetadataName && returnType.Kind == MemberKind.Void) {
kind = MemberKind.Destructor;
if (declaringType.BuiltinType == BuiltinTypeSpec.Type.Object) {
mod &= ~Modifiers.OVERRIDE;
}
}
- var mi = (MethodInfo) mb;
- returnType = ImportType (mi.ReturnType, new DynamicTypeReader (mi.ReturnParameter));
-
// Cannot set to OVERRIDE without full hierarchy checks
// this flag indicates that the method could be override
// but further validation is needed
// Strip reference wrapping
//
var el = p.ParameterType.GetElementType ();
- types[i] = ImportType (el, new DynamicTypeReader (p)); // TODO: 1-based positio to be csc compatible
+ types[i] = ImportType (el, new DynamicTypeReader (p), parent); // TODO: 1-based positio to be csc compatible
} else if (i == 0 && method.IsStatic && (parent.Modifiers & Modifiers.METHOD_EXTENSION) != 0 &&
HasAttribute (CustomAttributeData.GetCustomAttributes (method), "ExtensionAttribute", CompilerServicesNamespace)) {
mod = Parameter.Modifier.This;
- types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p));
+ types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p), parent);
} else {
- types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p));
+ types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p), parent);
if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
if (HasAttribute (CustomAttributeData.GetCustomAttributes (p), "ParamArrayAttribute", "System")) {
if (set_param_count == 0) {
set_based_param = ParametersCompiled.EmptyReadOnlyParameters;
} else {
- //
- // Create indexer parameters based on setter method parameters (the last parameter has to be removed)
- //
- var data = new IParameterData[set_param_count];
- var types = new TypeSpec[set_param_count];
- Array.Copy (set.Parameters.FixedParameters, data, set_param_count);
- Array.Copy (set.Parameters.Types, types, set_param_count);
- set_based_param = new ParametersImported (data, types, set.Parameters.HasParams);
+ set_based_param = IndexerSpec.CreateParametersFromSetter (set, set_param_count);
}
mod = set.Modifiers;
if (!param.IsEmpty) {
if (is_valid_property) {
var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember ();
- if (index_name == null) {
+ if (index_name == null || index_name != pi.Name) {
is_valid_property = false;
} else {
if (get != null) {
if (get.IsStatic)
is_valid_property = false;
- if (get.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
- is_valid_property = false;
}
if (set != null) {
if (set.IsStatic)
is_valid_property = false;
- if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
- is_valid_property = false;
}
}
if (t.Kind == MemberKind.MissingType)
spec = t;
else
- spec = MemberCache.FindNestedType (spec, t.Name, t.Arity);
+ spec = MemberCache.FindNestedType (spec, t.Name, t.Arity, false);
if (t.Arity > 0) {
spec = spec.MakeGenericType (module, targs.Skip (targs_pos).Take (spec.Arity).ToArray ());
if (index > 0)
name = name.Substring (0, index);
- spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos);
+ spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos, false);
if (spec.Arity > 0) {
spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ());
return found;
}
+ public ImportedAssemblyDefinition GetImportedAssemblyDefinition (AssemblyName assemblyName)
+ {
+ foreach (var a in Assemblies) {
+ var ia = a as ImportedAssemblyDefinition;
+ if (ia == null)
+ continue;
+
+ if (a.Name == assemblyName.Name)
+ return ia;
+ }
+
+ return null;
+ }
+
+
public void ImportTypeBase (MetaType type)
{
TypeSpec spec = import_cache[type];
}
}
- protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool importExtensionTypes)
+ public void ImportTypes (MetaType[] types, Namespace targetNamespace, bool importExtensionTypes)
{
Namespace ns = targetNamespace;
string prev_namespace = null;
public TypeSpec ImportType (MetaType type)
{
- return ImportType (type, new DynamicTypeReader (type));
+ return ImportType (type, new DynamicTypeReader (type), null);
}
- TypeSpec ImportType (MetaType type, DynamicTypeReader dtype)
+ TypeSpec ImportType (MetaType type, DynamicTypeReader dtype, TypeSpec currentType)
{
if (type.HasElementType) {
var element = type.GetElementType ();
++dtype.Position;
- var spec = ImportType (element, dtype);
+ var spec = ImportType (element, dtype, currentType);
if (type.IsArray)
return ArrayContainer.MakeType (module, spec, type.GetArrayRank ());
if (compiled_types.TryGetValue (type, out compiled_type)) {
if (compiled_type.BuiltinType == BuiltinTypeSpec.Type.Object && dtype.IsDynamicObject ())
return module.Compiler.BuiltinTypes.Dynamic;
+ } else {
+ compiled_type = CreateType (type, dtype, true);
+ }
- return compiled_type;
+ if (currentType == compiled_type && currentType?.IsGeneric == true) {
+ //
+ // Inflates current type to match behaviour of TypeDefinition::CurrentType used by compiled types
+ //
+ var targs = compiled_type.MemberDefinition.TypeParameters;
+ compiled_type = compiled_type.MakeGenericType (module, targs);
}
- return CreateType (type, dtype, true);
+ return compiled_type;
}
static bool IsMissingType (MetaType type)
token = null;
foreach (var internals in internals_visible_to) {
- if (internals.Name != assembly.Name)
+ if (!String.Equals(internals.Name, assembly.Name, StringComparison.OrdinalIgnoreCase))
continue;
if (token == null && assembly is AssemblyDefinition) {
if (s == null)
continue;
- var an = new AssemblyName (s);
+ AssemblyName an;
+ try {
+ an = new AssemblyName (s);
+ } catch (FileLoadException) {
+ // Invalid assembly name reuses FileLoadException
+ continue;
+ }
+
if (internals_visible_to == null)
internals_visible_to = new List<AssemblyName> ();