// Dual licensed under the terms of the MIT X11 or GNU GPL
//
// Copyright 2009-2011 Novell, Inc
-// Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+// 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 };
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";
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);
}
//
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);
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)
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)) {
}
}
- 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 (module, 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)
readonly Assembly assembly;
readonly AssemblyName aname;
bool cls_compliant;
- bool contains_extension_methods;
List<AssemblyName> internals_visible_to;
Dictionary<IAssemblyDefinition, AssemblyName> internals_visible_to_cache;
}
}
- public bool HasExtensionMethod {
- get {
- return contains_extension_methods;
- }
- }
-
public bool HasStrongName {
get {
return aname.GetPublicKey ().Length != 0;
internals_visible_to.Add (an);
continue;
}
-
- if (name == "ExtensionAttribute") {
- if (dt.Namespace == MetadataImporter.CompilerServicesNamespace)
- contains_extension_methods = true;
-
- continue;
- }
}
}
}
}
+ 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) {
"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) {
+ ctx.Module.Compiler.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 {
+ 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);
+ }
} else {
ctx.Module.Compiler.Report.Error (1684, loc,
"Reference to type `{0}' claims it is defined assembly `{1}', but it could not be found",
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;
throw new NotImplementedException (member.ToString ());
}
+ if (imported.IsStatic && declaringType.IsInterface)
+ continue;
+
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;