//
// Dual licensed under the terms of the MIT X11 or GNU GPL
//
-// Copyright 2009, 2010 Novell, Inc
+// Copyright 2009-2011 Novell, Inc
+// Copyright 2011-2012 Xamarin, Inc (http://www.xamarin.com)
//
using System;
// Dynamic types reader with additional logic to reconstruct a dynamic
// type using DynamicAttribute values
//
- struct DynamicTypeReader
+ protected struct DynamicTypeReader
{
static readonly bool[] single_attribute = { true };
}
if (cad.Count > 0) {
- string ns, name;
foreach (var ca in cad) {
- importer.GetCustomAttributeTypeName (ca, out ns, out name);
- if (name != "DynamicAttribute" && ns != CompilerServicesNamespace)
+ var dt = ca.Constructor.DeclaringType;
+ if (dt.Name != "DynamicAttribute" || dt.Namespace != CompilerServicesNamespace)
continue;
if (ca.ConstructorArguments.Count == 0) {
protected readonly Dictionary<MetaType, TypeSpec> import_cache;
protected readonly Dictionary<MetaType, TypeSpec> compiled_types;
protected readonly Dictionary<Assembly, IAssemblyDefinition> assembly_2_definition;
- readonly ModuleContainer module;
+ protected readonly ModuleContainer module;
public static readonly string CompilerServicesNamespace = "System.Runtime.CompilerServices";
public abstract void AddCompiledType (TypeBuilder builder, TypeSpec spec);
protected abstract MemberKind DetermineKindFromBaseType (MetaType baseType);
protected abstract bool HasVolatileModifier (MetaType[] modifiers);
- public abstract void GetCustomAttributeTypeName (CustomAttributeData cad, out string typeNamespace, out string typeName);
public FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType)
{
break;
default:
// Ignore private fields (even for error reporting) to not require extra dependencies
- if (IgnorePrivateMembers || HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "CompilerGeneratedAttribute", CompilerServicesNamespace))
+ if ((IgnorePrivateMembers && !declaringType.IsStruct) ||
+ HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "CompilerGeneratedAttribute", CompilerServicesNamespace))
return null;
mod = Modifiers.PRIVATE;
var definition = new ImportedMemberDefinition (fi, field_type, this);
if ((fa & FieldAttributes.Literal) != 0) {
- var c = Constant.CreateConstantFromValue (field_type, fi.GetRawConstantValue (), Location.Null);
+ Constant c = field_type.Kind == MemberKind.MissingType ?
+ new NullConstant (InternalType.ErrorType, Location.Null) :
+ Constant.CreateConstantFromValue (field_type, fi.GetRawConstantValue (), Location.Null);
return new ConstSpec (declaringType, definition, field_type, fi, mod, c);
}
// TODO: Sanity check on field_type (only few types are allowed)
var element_field = CreateField (fi.FieldType.GetField (FixedField.FixedElementName), declaringType);
- return new FixedFieldSpec (declaringType, definition, fi, element_field, mod);
+ return new FixedFieldSpec (module, declaringType, definition, fi, element_field, mod);
}
}
// Cannot set to OVERRIDE without full hierarchy checks
// this flag indicates that the method could be override
// but further validation is needed
- if ((mod & Modifiers.OVERRIDE) != 0 && kind == MemberKind.Method && declaringType.BaseType != null) {
- var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null);
- var candidate = MemberCache.FindMember (declaringType.BaseType, filter, BindingRestriction.None);
+ if ((mod & Modifiers.OVERRIDE) != 0) {
+ bool is_real_override = false;
+ if (kind == MemberKind.Method && declaringType.BaseType != null) {
+ var btype = declaringType.BaseType;
+ if (IsOverrideMethodBaseTypeAccessible (btype)) {
+ var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null);
+ var candidate = MemberCache.FindMember (btype, filter, BindingRestriction.None);
+
+ //
+ // For imported class method do additional validation to be sure that metadata
+ // override flag was correct
+ //
+ // Difference between protected internal and protected is ok
+ //
+ const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL;
+ if (candidate != null && (candidate.Modifiers & conflict_mask) == (mod & conflict_mask) && !candidate.IsStatic) {
+ is_real_override = true;
+ }
+ }
+ }
- //
- // For imported class method do additional validation to be sure that metadata
- // override flag was correct
- //
- // Difference between protected internal and protected is ok
- //
- const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL;
- if (candidate == null || (candidate.Modifiers & conflict_mask) != (mod & conflict_mask) || candidate.IsStatic) {
+ if (!is_real_override) {
mod &= ~Modifiers.OVERRIDE;
- mod |= Modifiers.VIRTUAL;
+ if ((mod & Modifiers.SEALED) != 0)
+ mod &= ~Modifiers.SEALED;
+ else
+ mod |= Modifiers.VIRTUAL;
}
}
}
- IMemberDefinition definition;
+ IMethodDefinition definition;
if (tparams != null) {
var gmd = new ImportedGenericMethodDefinition ((MethodInfo) mb, returnType, parameters, tparams, this);
foreach (var tp in gmd.TypeParameters) {
definition = gmd;
} else {
- definition = new ImportedParameterMemberDefinition (mb, returnType, parameters, this);
+ definition = new ImportedMethodDefinition (mb, returnType, parameters, this);
}
- MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod);
+ MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, parameters, mod);
if (tparams != null)
ms.IsGeneric = true;
return ms;
}
+ bool IsOverrideMethodBaseTypeAccessible (TypeSpec baseType)
+ {
+ switch (baseType.Modifiers & Modifiers.AccessibilityMask) {
+ case Modifiers.PUBLIC:
+ return true;
+ case Modifiers.INTERNAL:
+ //
+ // Check whether imported method in base type is accessible from compiled
+ // context
+ //
+ return baseType.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly);
+ case Modifiers.PRIVATE:
+ return false;
+ default:
+ // protected
+ // protected internal
+ //
+ // Method accessibility checks will be done later based on context
+ // where the method is called (CS0122 error will be reported for inaccessible)
+ //
+ return true;
+ }
+ }
+
//
// Imports System.Reflection parameters
//
//
var el = p.ParameterType.GetElementType ();
types[i] = ImportType (el, new DynamicTypeReader (p)); // TODO: 1-based positio to be csc compatible
- } else if (i == 0 && method.IsStatic && parent.IsStatic && parent.MemberDefinition.DeclaringAssembly.HasExtensionMethod &&
+ } 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);
if (!is_params && p.IsOptional) {
object value = p.RawDefaultValue;
var ptype = types[i];
- if ((p.Attributes & ParameterAttributes.HasDefault) != 0 && ptype.Kind != MemberKind.TypeParameter && (value != null || TypeManager.IsReferenceType (ptype))) {
+ if ((p.Attributes & ParameterAttributes.HasDefault) != 0 && ptype.Kind != MemberKind.TypeParameter && (value != null || TypeSpec.IsReferenceType (ptype))) {
if (value == null) {
- default_value = Constant.CreateConstant (ptype, null, Location.Null);
+ default_value = Constant.CreateConstantFromValue (ptype, null, Location.Null);
} else {
default_value = ImportParameterConstant (value);
default_value = new EnumConstant ((Constant) default_value, ptype);
}
}
+
+ var attrs = CustomAttributeData.GetCustomAttributes (p);
+ for (int ii = 0; ii < attrs.Count; ++ii) {
+ var attr = attrs[ii];
+ var dt = attr.Constructor.DeclaringType;
+ if (dt.Namespace != CompilerServicesNamespace)
+ continue;
+
+ if (dt.Name == "CallerLineNumberAttribute" && (ptype.BuiltinType == BuiltinTypeSpec.Type.Int || Convert.ImplicitNumericConversionExists (module.Compiler.BuiltinTypes.Int, ptype)))
+ mod |= Parameter.Modifier.CallerLineNumber;
+ else if (dt.Name == "CallerFilePathAttribute" && Convert.ImplicitReferenceConversionExists (module.Compiler.BuiltinTypes.String, ptype))
+ mod |= Parameter.Modifier.CallerFilePath;
+ else if (dt.Name == "CallerMemberNameAttribute" && Convert.ImplicitReferenceConversionExists (module.Compiler.BuiltinTypes.String, ptype))
+ mod |= Parameter.Modifier.CallerMemberName;
+ }
} else if (value == Missing.Value) {
default_value = EmptyExpression.MissingValue;
} else if (value == null) {
PropertySpec spec = null;
if (!param.IsEmpty) {
- var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember ();
- if (index_name == null) {
- 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 (is_valid_property) {
+ var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember ();
+ if (index_name == null) {
+ 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 (set != null) {
- if (set.IsStatic)
- is_valid_property = false;
- if (set.Name.IndexOf (index_name, StringComparison.Ordinal) != 4)
- is_valid_property = false;
+
+ if (is_valid_property) {
+ spec = new IndexerSpec (declaringType, new ImportedParameterMemberDefinition (pi, type, param, this), type, param, pi, mod);
+ } else if (declaringType.MemberDefinition.IsComImport && param.FixedParameters[0].HasDefaultValue) {
+ //
+ // Enables support for properties with parameters (must have default value) of COM-imported types
+ //
+ is_valid_property = true;
+
+ for (int i = 0; i < param.FixedParameters.Length; ++i) {
+ if (!param.FixedParameters[i].HasDefaultValue) {
+ is_valid_property = false;
+ break;
+ }
+ }
}
}
-
- if (is_valid_property)
- spec = new IndexerSpec (declaringType, new ImportedParameterMemberDefinition (pi, type, param, this), type, param, pi, mod);
}
if (spec == null)
spec = new PropertySpec (MemberKind.Property, declaringType, new ImportedMemberDefinition (pi, type, this), type, pi, mod);
if (!is_valid_property) {
- spec.IsNotRealProperty = true;
+ spec.IsNotCSharpCompatible = true;
return spec;
}
return CreateType (type, declaring_type, dtype, canImportBaseType);
}
- TypeSpec CreateType (MetaType type, TypeSpec declaringType, DynamicTypeReader dtype, bool canImportBaseType)
+ protected TypeSpec CreateType (MetaType type, TypeSpec declaringType, DynamicTypeReader dtype, bool canImportBaseType)
{
TypeSpec spec;
if (import_cache.TryGetValue (type, out spec)) {
if (type.IsGenericType && !type.IsGenericTypeDefinition) {
var type_def = type.GetGenericTypeDefinition ();
+
+ // Generic type definition can also be forwarded
+ if (compiled_types.TryGetValue (type_def, out spec))
+ return spec;
+
var targs = CreateGenericArguments (0, type.GetGenericArguments (), dtype);
if (declaringType == null) {
// Simple case, no nesting
for (int i = nested_hierarchy.Count; i != 0; --i) {
var t = nested_hierarchy [i - 1];
- spec = MemberCache.FindNestedType (spec, t.Name, t.Arity);
+ if (t.Kind == MemberKind.MissingType)
+ spec = t;
+ else
+ spec = MemberCache.FindNestedType (spec, t.Name, t.Arity);
+
if (t.Arity > 0) {
spec = spec.MakeGenericType (module, targs.Skip (targs_pos).Take (spec.Arity).ToArray ());
targs_pos += t.Arity;
}
}
- string name = type.Name;
- int index = name.IndexOf ('`');
- if (index > 0)
- name = name.Substring (0, index);
+ if (spec.Kind == MemberKind.MissingType) {
+ spec = new TypeSpec (MemberKind.MissingType, spec, new ImportedTypeDefinition (type_def, this), type_def, Modifiers.PUBLIC);
+ spec.MemberCache = MemberCache.Empty;
+ } else {
+ if ((type_def.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate && IgnorePrivateMembers)
+ return null;
+
+ string name = type.Name;
+ int index = name.IndexOf ('`');
+ 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);
- if (spec.Arity > 0) {
- spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ());
+ if (spec.Arity > 0) {
+ spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ());
+ }
}
}
import_cache.Add (type, spec);
+ if (kind == MemberKind.TypeParameter) {
+ if (canImportBaseType)
+ ImportTypeParameterTypeConstraints ((TypeParameterSpec) spec, type);
+
+ return spec;
+ }
+
//
// Two stage setup as the base type can be inflated declaring type or
// another nested type inside same declaring type which has not been
if (!assembly_2_definition.TryGetValue (assembly, out found)) {
// This can happen in dynamic context only
- var def = new ImportedAssemblyDefinition (assembly, this);
+ var def = new ImportedAssemblyDefinition (assembly);
assembly_2_definition.Add (assembly, def);
def.ReadAttributes ();
found = def;
// Test for a custom attribute type match. Custom attributes are not really predefined globaly
// they can be assembly specific therefore we do check based on names only
//
- public bool HasAttribute (IList<CustomAttributeData> attributesData, string attrName, string attrNamespace)
+ public static bool HasAttribute (IList<CustomAttributeData> attributesData, string attrName, string attrNamespace)
{
if (attributesData.Count == 0)
return false;
- string ns, name;
foreach (var attr in attributesData) {
- GetCustomAttributeTypeName (attr, out ns, out name);
- if (name == attrName && ns == attrNamespace)
+ var dt = attr.Constructor.DeclaringType;
+ if (dt.Name == attrName && dt.Namespace == attrNamespace)
return true;
}
spec.BaseType = base_type;
}
- MetaType[] ifaces;
-#if STATIC
- ifaces = type.__GetDeclaredInterfaces ();
- if (ifaces.Length != 0) {
- foreach (var iface in ifaces) {
- var it = CreateType (iface);
- spec.AddInterface (it);
-
- // Unfortunatelly not all languages inlcude inherited interfaces
- var bifaces = it.Interfaces;
- if (bifaces != null) {
- foreach (var biface in bifaces) {
- spec.AddInterface (biface);
- }
- }
- }
- }
-
- if (spec.BaseType != null) {
- var bifaces = spec.BaseType.Interfaces;
- if (bifaces != null) {
- foreach (var iface in bifaces)
- spec.AddInterface (iface);
- }
- }
-#else
- ifaces = type.GetInterfaces ();
-
- if (ifaces.Length > 0) {
- foreach (var iface in ifaces) {
- spec.AddInterface (CreateType (iface));
- }
- }
-#endif
-
if (spec.MemberDefinition.TypeParametersCount > 0) {
foreach (var tp in spec.MemberDefinition.TypeParameters) {
ImportTypeParameterTypeConstraints (tp, tp.GetMetaInfo ());
}
}
-
}
- protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool hasExtensionTypes)
+ protected void ImportTypes (MetaType[] types, Namespace targetNamespace, bool importExtensionTypes)
{
Namespace ns = targetNamespace;
string prev_namespace = null;
prev_namespace = t.Namespace;
}
- ns.AddType (it);
-
- if (it.IsStatic && hasExtensionTypes &&
+ // Cannot rely on assembly level Extension attribute or static modifier because they
+ // are not followed by other compilers (e.g. F#).
+ if (it.IsClass && it.Arity == 0 && importExtensionTypes &&
HasAttribute (CustomAttributeData.GetCustomAttributes (t), "ExtensionAttribute", CompilerServicesNamespace)) {
it.SetExtensionMethodContainer ();
}
+
+ ns.AddType (module, it);
}
}
continue;
}
- if (!IsMissingType (ct) && ct.IsClass) {
- spec.BaseType = CreateType (ct);
+ var constraint_type = CreateType (ct);
+ if (constraint_type.IsClass) {
+ spec.BaseType = constraint_type;
continue;
}
- spec.AddInterface (CreateType (ct));
+ spec.AddInterface (constraint_type);
}
if (spec.BaseType == null)
if (attrs.Count == 0)
return null;
- string name, ns;
foreach (var ca in attrs) {
- GetCustomAttributeTypeName (ca, out ns, out name);
- if (name != "DecimalConstantAttribute" || ns != CompilerServicesNamespace)
+ var dt = ca.Constructor.DeclaringType;
+ if (dt.Name != "DecimalConstantAttribute" || dt.Namespace != CompilerServicesNamespace)
continue;
var value = new decimal (
return mod;
}
+ // It can be sealed and override
if ((ma & MethodAttributes.Final) != 0)
mod |= Modifiers.SEALED;
- // It can be sealed and override
if ((ma & MethodAttributes.Virtual) != 0) {
- if ((ma & MethodAttributes.NewSlot) != 0 || !declaringType.IsClass) {
- // No private virtual or sealed virtual
- if ((mod & (Modifiers.PRIVATE | Modifiers.SEALED)) == 0)
+ // Not every member can be detected based on MethodAttribute, we
+ // set virtual or non-virtual only when we are certain. Further checks
+ // to really find out what `virtual' means for this member are done
+ // later
+ if ((ma & MethodAttributes.NewSlot) != 0) {
+ if ((mod & Modifiers.SEALED) != 0) {
+ mod &= ~Modifiers.SEALED;
+ } else {
mod |= Modifiers.VIRTUAL;
+ }
} else {
mod |= Modifiers.OVERRIDE;
}
// It should not throw any loading exception
IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes (mi);
- string ns, name;
foreach (var a in attrs) {
- importer.GetCustomAttributeTypeName (a, out ns, out name);
+ var dt = a.Constructor.DeclaringType;
+ string name = dt.Name;
if (name == "ObsoleteAttribute") {
- if (ns != "System")
+ if (dt.Namespace != "System")
continue;
if (bag == null)
}
if (name == "ConditionalAttribute") {
- if (ns != "System.Diagnostics")
+ if (dt.Namespace != "System.Diagnostics")
continue;
if (bag == null)
}
if (name == "CLSCompliantAttribute") {
- if (ns != "System")
+ if (dt.Namespace != "System")
continue;
if (bag == null)
// Type only attributes
if (mi.MemberType == MemberTypes.TypeInfo || mi.MemberType == MemberTypes.NestedType) {
if (name == "DefaultMemberAttribute") {
- if (ns != "System.Reflection")
+ if (dt.Namespace != "System.Reflection")
continue;
if (bag == null)
}
if (name == "AttributeUsageAttribute") {
- if (ns != "System")
+ if (dt.Namespace != "System")
continue;
if (bag == null)
// Interface only attribute
if (name == "CoClassAttribute") {
- if (ns != "System.Runtime.InteropServices")
+ if (dt.Namespace != "System.Runtime.InteropServices")
continue;
if (bag == null)
{
readonly Module module;
bool cls_compliant;
- readonly MetadataImporter importer;
- public ImportedModuleDefinition (Module module, MetadataImporter importer)
+ public ImportedModuleDefinition (Module module)
{
this.module = module;
- this.importer = importer;
}
#region Properties
{
IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes (module);
- string ns, name;
foreach (var a in attrs) {
- importer.GetCustomAttributeTypeName (a, out ns, out name);
- if (name == "CLSCompliantAttribute") {
- if (ns != "System")
+ var dt = a.Constructor.DeclaringType;
+ if (dt.Name == "CLSCompliantAttribute") {
+ if (dt.Namespace != "System")
continue;
cls_compliant = (bool) a.ConstructorArguments[0].Value;
{
readonly Assembly assembly;
readonly AssemblyName aname;
- readonly MetadataImporter importer;
bool cls_compliant;
- bool contains_extension_methods;
List<AssemblyName> internals_visible_to;
Dictionary<IAssemblyDefinition, AssemblyName> internals_visible_to_cache;
- public ImportedAssemblyDefinition (Assembly assembly, MetadataImporter importer)
+ public ImportedAssemblyDefinition (Assembly assembly)
{
this.assembly = assembly;
this.aname = assembly.GetName ();
- this.importer = importer;
}
#region Properties
}
}
- public bool HasExtensionMethod {
- get {
- return contains_extension_methods;
- }
- }
-
public bool HasStrongName {
get {
return aname.GetPublicKey ().Length != 0;
IList<CustomAttributeData> attrs = CustomAttributeData.GetCustomAttributes (assembly);
- string ns, name;
foreach (var a in attrs) {
- importer.GetCustomAttributeTypeName (a, out ns, out name);
-
+ var dt = a.Constructor.DeclaringType;
+ var name = dt.Name;
if (name == "CLSCompliantAttribute") {
- if (ns == "System") {
- try {
- cls_compliant = (bool) a.ConstructorArguments[0].Value;
- } catch {
- }
+ if (dt.Namespace == "System") {
+ cls_compliant = (bool) a.ConstructorArguments[0].Value;
}
continue;
}
if (name == "InternalsVisibleToAttribute") {
- if (ns != MetadataImporter.CompilerServicesNamespace)
+ if (dt.Namespace != MetadataImporter.CompilerServicesNamespace)
continue;
- string s;
- try {
- s = a.ConstructorArguments[0].Value as string;
- } catch {
- s = null;
- }
-
+ string s = a.ConstructorArguments[0].Value as string;
if (s == null)
continue;
internals_visible_to.Add (an);
continue;
}
-
- if (name == "ExtensionAttribute") {
- if (ns == MetadataImporter.CompilerServicesNamespace)
- contains_extension_methods = true;
-
- continue;
- }
}
}
{
readonly AParametersCollection parameters;
- public ImportedParameterMemberDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
+ protected ImportedParameterMemberDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
: base (provider, type, importer)
{
this.parameters = parameters;
#endregion
}
- class ImportedGenericMethodDefinition : ImportedParameterMemberDefinition, IGenericMethodDefinition
+ class ImportedMethodDefinition : ImportedParameterMemberDefinition, IMethodDefinition
+ {
+ public ImportedMethodDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
+ : base (provider, type, parameters, importer)
+ {
+ }
+
+ MethodBase IMethodDefinition.Metadata {
+ get {
+ return (MethodBase) provider;
+ }
+ }
+ }
+
+ class ImportedGenericMethodDefinition : ImportedMethodDefinition, IGenericMethodDefinition
{
readonly TypeParameterSpec[] tparams;
}
}
+ bool ITypeDefinition.IsComImport {
+ get {
+ return ((MetaType) provider).IsImport;
+ }
+ }
+
+
+ bool ITypeDefinition.IsPartial {
+ get {
+ return false;
+ }
+ }
+
+ bool ITypeDefinition.IsTypeForwarder {
+ get {
+#if STATIC
+ return ((MetaType) provider).__IsTypeForwarder;
+#else
+ return false;
+#endif
+ }
+ }
+
public override string Name {
get {
if (name == null) {
#endregion
+ public void DefineInterfaces (TypeSpec spec)
+ {
+ var type = (MetaType) provider;
+ MetaType[] ifaces;
+#if STATIC
+ ifaces = type.__GetDeclaredInterfaces ();
+ if (ifaces.Length != 0) {
+ foreach (var iface in ifaces) {
+ var it = importer.CreateType (iface);
+ if (it == null)
+ continue;
+
+ spec.AddInterfaceDefined (it);
+
+ // Unfortunately not all languages expand inherited interfaces
+ var bifaces = it.Interfaces;
+ if (bifaces != null) {
+ foreach (var biface in bifaces) {
+ spec.AddInterfaceDefined (biface);
+ }
+ }
+ }
+ }
+
+ //
+ // It's impossible to get declared interfaces only using System.Reflection
+ // hence we need to mimic the behavior with ikvm-reflection too to keep
+ // our type look-up logic same
+ //
+ if (spec.BaseType != null) {
+ var bifaces = spec.BaseType.Interfaces;
+ if (bifaces != null) {
+ //
+ // Before adding base class interfaces close defined interfaces
+ // on type parameter
+ //
+ var tp = spec as TypeParameterSpec;
+ if (tp != null && tp.InterfacesDefined == null) {
+ tp.InterfacesDefined = TypeSpec.EmptyTypes;
+ }
+
+ foreach (var iface in bifaces)
+ spec.AddInterfaceDefined (iface);
+ }
+ }
+#else
+ ifaces = type.GetInterfaces ();
+
+ if (ifaces.Length > 0) {
+ foreach (var iface in ifaces) {
+ spec.AddInterface (importer.CreateType (iface));
+ }
+ }
+#endif
+
+ }
+
public static void Error_MissingDependency (IMemberContext ctx, List<TypeSpec> types, Location loc)
{
//
// or referenced from the user core in which case compilation error has to
// be reported because compiler cannot continue anyway
//
- foreach (var t in types) {
+
+ var report = ctx.Module.Compiler.Report;
+
+ for (int i = 0; i < types.Count; ++i) {
+ var t = types [i];
+
+ //
+ // Report missing types only once
+ //
+ if (report.Printer.MissingTypeReported (t.MemberDefinition))
+ continue;
+
string name = t.GetSignatureForError ();
if (t.MemberDefinition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {
- ctx.Module.Compiler.Report.Error (1683, loc,
+ report.Error (1683, loc,
"Reference to type `{0}' claims it is defined in this assembly, but it is not defined in source or any added modules",
name);
} else if (t.MemberDefinition.DeclaringAssembly.IsMissing) {
- ctx.Module.Compiler.Report.Error (12, loc,
- "The type `{0}' is defined in an assembly that is not referenced. Consider adding a reference to assembly `{1}'",
- name, t.MemberDefinition.DeclaringAssembly.FullName);
+ if (t.MemberDefinition.IsTypeForwarder) {
+ report.Error (1070, loc,
+ "The type `{0}' has been forwarded to an assembly that is not referenced. Consider adding a reference to assembly `{1}'",
+ name, t.MemberDefinition.DeclaringAssembly.FullName);
+ } else {
+ report.Error (12, loc,
+ "The type `{0}' is defined in an assembly that is not referenced. Consider adding a reference to assembly `{1}'",
+ name, t.MemberDefinition.DeclaringAssembly.FullName);
+ }
} else {
- ctx.Module.Compiler.Report.Error (1684, loc,
+ report.Error (1684, loc,
"Reference to type `{0}' claims it is defined assembly `{1}', but it could not be found",
name, t.MemberDefinition.DeclaringAssembly.FullName);
}
if ((t.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate && importer.IgnorePrivateMembers)
continue;
- imported = importer.CreateNestedType (t, declaringType);
+ try {
+ imported = importer.CreateNestedType (t, declaringType);
+ } catch (Exception e) {
+ throw new InternalErrorException (e, "Could not import nested type `{0}' from `{1}'",
+ t.FullName, declaringType.MemberDefinition.DeclaringAssembly.FullName);
+ }
+
cache.AddMemberImported (imported);
}
}
}
+ //
+ // Load base interfaces first to minic behaviour of compiled members
+ //
+ if (declaringType.IsInterface && declaringType.Interfaces != null) {
+ foreach (var iface in declaringType.Interfaces) {
+ cache.AddInterface (iface);
+ }
+ }
+
if (!onlyTypes) {
//
// The logic here requires methods to be returned first which seems to work for both Mono and .NET
foreach (var member in all) {
switch (member.MemberType) {
case MemberTypes.Constructor:
+ if (declaringType.IsInterface)
+ continue;
+
+ goto case MemberTypes.Method;
case MemberTypes.Method:
MethodBase mb = (MethodBase) member;
var attrs = mb.Attributes;
continue;
// Ignore compiler generated methods
- if (importer.HasAttribute (CustomAttributeData.GetCustomAttributes (mb), "CompilerGeneratedAttribute", MetadataImporter.CompilerServicesNamespace))
+ if (MetadataImporter.HasAttribute (CustomAttributeData.GetCustomAttributes (mb), "CompilerGeneratedAttribute", MetadataImporter.CompilerServicesNamespace))
continue;
}
throw new NotImplementedException (member.ToString ());
}
- cache.AddMemberImported (imported);
- }
- }
+ if (imported.IsStatic && declaringType.IsInterface)
+ continue;
- if (declaringType.IsInterface && declaringType.Interfaces != null) {
- foreach (var iface in declaringType.Interfaces) {
- cache.AddInterface (iface);
+ cache.AddMemberImported (imported);
}
}
}
}
}
+ bool ITypeDefinition.IsComImport {
+ get {
+ return false;
+ }
+ }
+
+ bool ITypeDefinition.IsPartial {
+ get {
+ return false;
+ }
+ }
+
+ bool ITypeDefinition.IsTypeForwarder {
+ get {
+ return false;
+ }
+ }
+
public string Namespace {
get {
return null;