@ -6,7 +6,7 @@
@@ -6,7 +6,7 @@
// 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 ;
@ -32,7 +32,7 @@ namespace Mono.CSharp
@@ -32,7 +32,7 @@ namespace Mono.CSharp
// 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 } ;
@ -120,7 +120,7 @@ namespace Mono.CSharp
@@ -120,7 +120,7 @@ namespace Mono.CSharp
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" ;
@ -191,7 +191,9 @@ namespace Mono.CSharp
@@ -191,7 +191,9 @@ namespace Mono.CSharp
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 ) ;
}
@ -489,7 +491,7 @@ namespace Mono.CSharp
@@ -489,7 +491,7 @@ namespace Mono.CSharp
//
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 ) ;
@ -508,7 +510,7 @@ namespace Mono.CSharp
@@ -508,7 +510,7 @@ namespace Mono.CSharp
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 ) ;
@ -516,6 +518,21 @@ namespace Mono.CSharp
@@ -516,6 +518,21 @@ namespace Mono.CSharp
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 ) {
@ -618,26 +635,41 @@ namespace Mono.CSharp
@@ -618,26 +635,41 @@ namespace Mono.CSharp
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 )
@ -677,7 +709,7 @@ namespace Mono.CSharp
@@ -677,7 +709,7 @@ namespace Mono.CSharp
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 ) ) {
@ -995,6 +1027,11 @@ namespace Mono.CSharp
@@ -995,6 +1027,11 @@ namespace Mono.CSharp
}
}
//
// 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 ) {
@ -1028,7 +1065,7 @@ namespace Mono.CSharp
@@ -1028,7 +1065,7 @@ namespace Mono.CSharp
}
}
protected void ImportTypes ( MetaType [ ] types , Namespace targetNamespace , bool has ExtensionTypes)
protected void ImportTypes ( MetaType [ ] types , Namespace targetNamespace , bool import ExtensionTypes)
{
Namespace ns = targetNamespace ;
string prev_namespace = null ;
@ -1052,12 +1089,14 @@ namespace Mono.CSharp
@@ -1052,12 +1089,14 @@ namespace Mono.CSharp
prev_namespace = t . Namespace ;
}
ns . AddType ( module , it ) ;
if ( it . IsStatic & & has ExtensionTypes & &
// 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 & & import ExtensionTypes & &
HasAttribute ( CustomAttributeData . GetCustomAttributes ( t ) , "ExtensionAttribute" , CompilerServicesNamespace ) ) {
it . SetExtensionMethodContainer ( ) ;
}
ns . AddType ( module , it ) ;
}
}
@ -1074,12 +1113,13 @@ namespace Mono.CSharp
@@ -1074,12 +1113,13 @@ namespace Mono.CSharp
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 )
@ -1520,7 +1560,6 @@ namespace Mono.CSharp
@@ -1520,7 +1560,6 @@ namespace Mono.CSharp
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 ;
@ -1545,12 +1584,6 @@ namespace Mono.CSharp
@@ -1545,12 +1584,6 @@ namespace Mono.CSharp
}
}
public bool HasExtensionMethod {
get {
return contains_extension_methods ;
}
}
public bool HasStrongName {
get {
return aname . GetPublicKey ( ) . Length ! = 0 ;
@ -1668,13 +1701,6 @@ namespace Mono.CSharp
@@ -1668,13 +1701,6 @@ namespace Mono.CSharp
internals_visible_to . Add ( an ) ;
continue ;
}
if ( name = = "ExtensionAttribute" ) {
if ( dt . Namespace = = MetadataImporter . CompilerServicesNamespace )
contains_extension_methods = true ;
continue ;
}
}
}
@ -1777,12 +1803,29 @@ namespace Mono.CSharp
@@ -1777,12 +1803,29 @@ namespace Mono.CSharp
}
}
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 ) {
@ -1845,9 +1888,15 @@ namespace Mono.CSharp
@@ -1845,9 +1888,15 @@ namespace Mono.CSharp
"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 ( 1 2 , 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 ( 1 0 7 0 , 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 ( 1 2 , 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 ( 1 6 8 4 , loc ,
"Reference to type `{0}' claims it is defined assembly `{1}', but it could not be found" ,
@ -2122,12 +2171,24 @@ namespace Mono.CSharp
@@ -2122,12 +2171,24 @@ namespace Mono.CSharp
}
}
bool ITypeDefinition . IsComImport {
get {
return false ;
}
}
bool ITypeDefinition . IsPartial {
get {
return false ;
}
}
bool ITypeDefinition . IsTypeForwarder {
get {
return false ;
}
}
public string Namespace {
get {
return null ;