//
// Returns true when object at local position has dynamic attribute flag
//
- public bool IsDynamicObject (MetadataImporter importer)
+ public bool IsDynamicObject ()
{
if (provider != null)
- ReadAttribute (importer);
+ ReadAttribute ();
return flags != null && Position < flags.Length && flags[Position];
}
//
// Returns true when DynamicAttribute exists
//
- public bool HasDynamicAttribute (MetadataImporter importer)
+ public bool HasDynamicAttribute ()
{
if (provider != null)
- ReadAttribute (importer);
+ ReadAttribute ();
return flags != null;
}
- void ReadAttribute (MetadataImporter importer)
+ void ReadAttribute ()
{
IList<CustomAttributeData> cad;
if (provider is MemberInfo) {
public FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType)
{
- Modifiers mod = 0;
+ Modifiers mod;
var fa = fi.Attributes;
switch (fa & FieldAttributes.FieldAccessMask) {
case FieldAttributes.Public:
// 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);
}
}
// IFoo<A<T>> foo; // A<T> is definition in this case
// }
//
- // TODO: Is full logic from CreateType needed here as well?
- //
if (!IsMissingType (type) && type.IsGenericTypeDefinition) {
- var targs = CreateGenericArguments (0, type.GetGenericArguments (), dtype);
+ var start_pos = spec.DeclaringType == null ? 0 : spec.DeclaringType.MemberDefinition.TypeParametersCount;
+ var targs = CreateGenericArguments (start_pos, type.GetGenericArguments (), dtype);
spec = spec.MakeGenericType (module, targs);
}
}
}
}
- 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;
var ptype = types[i];
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) {
TypeSpec spec;
if (import_cache.TryGetValue (type, out spec)) {
if (spec.BuiltinType == BuiltinTypeSpec.Type.Object) {
- if (dtype.IsDynamicObject (this))
+ if (dtype.IsDynamicObject ())
return module.Compiler.BuiltinTypes.Dynamic;
return spec;
if (!spec.IsGeneric || type.IsGenericTypeDefinition)
return spec;
- if (!dtype.HasDynamicAttribute (this))
+ if (!dtype.HasDynamicAttribute ())
return spec;
// We've found same object in the cache but this one has a dynamic custom attribute
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;
- spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos);
- if (spec == null)
- return null;
+ string name = type.Name;
+ int index = name.IndexOf ('`');
+ if (index > 0)
+ name = name.Substring (0, index);
- if (spec.Arity > 0) {
- spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ());
+ spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos);
+
+ if (spec.Arity > 0) {
+ spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ());
+ }
}
}
if (kind == MemberKind.Class) {
if ((ma & TypeAttributes.Sealed) != 0) {
- mod |= Modifiers.SEALED;
if ((ma & TypeAttributes.Abstract) != 0)
mod |= Modifiers.STATIC;
+ else
+ mod |= Modifiers.SEALED;
} else if ((ma & TypeAttributes.Abstract) != 0) {
mod |= Modifiers.ABSTRACT;
}
spec.BaseType = base_type;
}
- MetaType[] ifaces;
-#if STATIC
- ifaces = type.__GetDeclaredInterfaces ();
- if (ifaces.Length != 0) {
- foreach (var iface in ifaces) {
- var it = CreateType (iface);
- if (it == null)
- continue;
-
- spec.AddInterface (it);
-
- // Unfortunately not all languages expand 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) {
- //
- // 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.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 AttributesBag cattrs;
protected readonly MetadataImporter importer;
- public ImportedDefinition (MemberInfo provider, MetadataImporter importer)
+ protected ImportedDefinition (MemberInfo provider, MetadataImporter importer)
{
this.provider = provider;
this.importer = importer;
{
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.IsCyclicTypeForwarder {
+ get {
+#if STATIC
+ return ((MetaType) provider).__IsCyclicTypeForwarder;
+#else
+ return false;
+#endif
+ }
+ }
+
public override string Name {
get {
if (name == null) {
#endregion
- public static void Error_MissingDependency (IMemberContext ctx, List<TypeSpec> types, Location loc)
+ 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<MissingTypeSpecReference> missing, Location loc)
{
//
// Report details about missing type and most likely cause of the problem.
// or referenced from the user core in which case compilation error has to
// be reported because compiler cannot continue anyway
//
- for (int i = 0; i < types.Count; ++i) {
- var t = types [i];
+
+ var report = ctx.Module.Compiler.Report;
+
+ for (int i = 0; i < missing.Count; ++i) {
+ var t = missing [i].Type;
//
- // Report missing types only once per type
+ // Report missing types only once
//
- if (i > 0 && types.IndexOf (t) < i)
+ 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,
+ var caller = missing[i].Caller;
+ if (caller.Kind != MemberKind.MissingType)
+ report.SymbolRelatedToPreviousError (caller);
+
+ var definition = t.MemberDefinition;
+ if (definition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {
+ 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) {
- if (t.MemberDefinition.IsTypeForwarder) {
- ctx.Module.Compiler.Report.Error (1070, loc,
+ } else if (definition.DeclaringAssembly.IsMissing) {
+ if (definition.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);
+ name, definition.DeclaringAssembly.FullName);
} else {
- ctx.Module.Compiler.Report.Error (12, loc,
+ 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);
+ name, definition.DeclaringAssembly.FullName);
}
+ } else if (definition.IsTypeForwarder) {
+ report.Error (731, loc, "The type forwarder for type `{0}' in assembly `{1}' has circular dependency",
+ name, definition.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 (get == null && set == null)
continue;
- imported = importer.CreateProperty (p, declaringType, get, set);
+ try {
+ imported = importer.CreateProperty (p, declaringType, get, set);
+ } catch (Exception ex) {
+ throw new InternalErrorException (ex, "Could not import property `{0}' inside `{1}'",
+ p.Name, declaringType.GetSignatureForError ());
+ }
+
if (imported == null)
continue;
}
}
+ bool ITypeDefinition.IsCyclicTypeForwarder {
+ get {
+ return false;
+ }
+ }
+
public string Namespace {
get {
return null;