using System.Reflection;
using System.Runtime.CompilerServices;
-[assembly: AssemblyVersion("0.29.99")]
+[assembly: AssemblyVersion("0.30.99")]
[assembly: AssemblyTitle ("Mono C# Compiler")]
[assembly: AssemblyDescription ("Mono C# Compiler with Generics")]
[assembly: AssemblyCopyright ("2001, 2002, 2003 Ximian, Inc.")]
+2004-02-26 Miguel de Icaza <miguel@ximian.com>
+
+ * iterators.cs (IteratorHandler.IsIEnumerator, IsIEnumerable): New
+ routines to check if a type is an enumerable/enumerator allow
+ classes that implement the IEnumerable or IEnumerator interfaces.
+
+ * class.cs (Property, Operator): Implement IIteratorContainer, and
+ implement SetYields.
+
+ (Property.Define): Do the block swapping for get_methods in the
+ context of iterators. We need to check if Properties also
+ include indexers or not.
+
+ (Operator): Assign the Block before invoking the
+ OperatorMethod.Define, so we can trigger the Iterator code
+ replacement.
+
+ * cs-parser.jay (SimpleIteratorContainer): new helper class. Both
+ Property and Operator classes are not created when we parse the
+ declarator but until we have the block completed, so we use a
+ singleton SimpleIteratorContainer.Simple to flag whether the
+ SetYields has been invoked.
+
+ We propagate this setting then to the Property or the Operator to
+ allow the `yield' to function.
+
+2004-02-25 Marek Safar <marek.safar@seznam.cz>
+
+ * codegen.cs: Implemented attribute support for modules.
+ New AssemblyClass, ModuleClass and CommonAssemblyModulClass for
+ Assembly/Module functionality.
+
+ * attribute.cs, class.cs, cs-parser.jay, delegate.cs, driver.cs, enum.cs
+ interface.cs, rootcontext.cs, statement.cs, typemanager.cs:
+ Updated dependencies on CodeGen.ModuleBuilder and CodeGen.AssemblyBuilder.
+
+2004-02-16 Marek Safar <marek.safar@seznam.cz>
+
+ * interface.cs (FindMembers): The operation is performed on all base
+ interfaces and not only on the first. It is required for future CLS Compliance patch.
+
+2004-02-12 Ben Maurer <bmaurer@users.sourceforge.net>
+
+ * statement.cs, codegen.cs:
+ This patch deals with patterns such as:
+
+ public class List : IEnumerable {
+
+ public MyEnumerator GetEnumerator () {
+ return new MyEnumerator(this);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator () {
+ ...
+ }
+
+ public struct MyEnumerator : IEnumerator {
+ ...
+ }
+ }
+
+ Before, there were a few things we did wrong:
+ 1) we would emit callvirt on a struct, which is illegal
+ 2) we emited ldarg when we needed to emit ldarga
+ 3) we would mistakenly call the interface methods on an enumerator
+ type that derived from IEnumerator and was in another assembly. For example:
+
+ public class MyEnumerator : IEnumerator
+
+ Would have the interface methods called, even if there were public impls of the
+ method. In a struct, this lead to invalid IL code.
+
+2004-02-11 Marek Safar <marek.safar@seznam.cz>
+
+ * const.cs: Const is now derived from FieldBase. Method EmitConstant name
+ renamed to Emit.
+
+ * delegate.cs (Define): Fixed crash when delegate type is undefined.
+
+2004-02-11 Miguel de Icaza <miguel@ximian.com>
+
+ * cs-parser.jay: Fix small regression: we were not testing V2
+ compiler features correctly.
+
+ * interface.cs: If the emit context is null, then create one
+
+2004-02-09 Marek Safar <marek.safar@seznam.cz>
+
+ * decl.cs (GetSignatureForError): New virtual method to get full name
+ for error messages.
+
+ * attribute.cs (IAttributeSupport): New interface for attribute setting.
+ Now it is possible to rewrite ApplyAttributes method to be less if/else.
+
+ * interface.cs : All InterfaceXXX classes are now derived from MemberCore.
+ Duplicated members and code in these classes has been removed.
+ Better encapsulation in these classes.
+
+2004-02-07 Miguel de Icaza <miguel@ximian.com>
+
+ * assign.cs (Assign.DoResolve): When dealing with compound
+ assignments, there is a new rule in ECMA C# 2.4 (might have been
+ there before, but it is documented here) that states that in:
+
+ a op= b;
+
+ If b is of type int, and the `op' is a shift-operator, then the
+ above is evaluated as:
+
+ a = (int) a op b
+
+ * expression.cs (Binary.ResolveOperator): Instead of testing for
+ int/uint/long/ulong, try to implicitly convert to any of those
+ types and use that in pointer arithmetic.
+
+ * delegate.cs (Error_NoMatchingMethodForDelegate): Compute the
+ method to print information for from the type, not from the
+ null-method we were given.
+
+2004-02-01 Duncan Mak <duncan@ximian.com>
+
+ * cs-tokenizer.cs (get_cmd_arg): Skip over whitespace before
+ parsing for cmd, fixes bug #53694.
+
+2004-02-04 Marek Safar <marek.safar@seznam.cz>
+
+ * class.cs, decl.cs: Fixed problem where IndexerName attribute was ignored
+ in the member name duplication tests. Property and operator name duplication
+ was missing too (error tests cs0102-{2,3,4,5}.cs, cs0111-{3,4}.cs).
+
+2004-02-03 Marek Safar <marek.safar@seznam.cz>
+
+ * interface.cs (PopulateMethod): Fixed crash when interface method
+ returns not existing type (error test cs0246-3.cs).
+
+2004-02-02 Ravi Pratap M <ravi@ximian.com>
+
+ * cs-parser.jay (interface_accessors): Re-write actions to also
+ store attributes attached to get and set methods. Fix spelling
+ while at it.
+
+ (inteface_property_declaration): Modify accordingly.
+
+ (InterfaceAccessorInfo): New helper class to store information to pass
+ around between rules that use interface_accessors.
+
+ * interface.cs (Emit): Apply attributes on the get and set
+ accessors of properties and indexers too.
+
+ * attribute.cs (ApplyAttributes): Modify accordingly to use the
+ right MethodBuilder when applying attributes to the get and set accessors.
+
+2004-01-31 Miguel de Icaza <miguel@ximian.com>
+
+ * cs-tokenizer.cs: Applied patch from Marek Safar to fix bug 53386
+
+2004-01-26 Miguel de Icaza <miguel@ximian.com>
+
+ * cs-tokenizer.cs: Handle #line hidden from PDC bits.
+
+2004-01-25 Miguel de Icaza <miguel@ximian.com>
+
+ * cs-parser.jay: Remove YIELD token, instead use the new grammar
+ changes that treat `yield' specially when present before `break'
+ or `return' tokens.
+
+ * cs-tokenizer.cs: yield is no longer a keyword.
+
+2004-01-23 Marek Safar <marek.safar@seznam.cz>
+
+ * cs-parser.jay, class.cs (DefineDefaultConstructor): Fixed ModFlags
+ setting for default constructors.
+ For default constructors are almost every time set wrong Modifier. The
+ generated IL code has been alright. But inside mcs this values was
+ wrong and this was reason why several of my CLS Compliance tests
+ failed.
+
2004-02-27 Martin Baulig <martin@ximian.com>
* generics.cs (ConstructedType.ResolveType): Make the nested type
mcs3.exe: mcs2.exe
$(TIME) $(RUNTIME) ./mcs2.exe $(USE_MCS_FLAGS) /target:exe /out:$@ $(all_sources)
+wc:
+ wc -l $(all_sources)
+
ctest:
-rm mcs2.exe mcs3.exe
make btest USE_MCS_FLAGS=
//
// 2. and the original right side is implicitly convertible to
- // the type of target_type.
+ // the type of target
//
if (Convert.ImplicitStandardConversionExists (a.original_source, target_type))
return this;
+ //
+ // In the spec 2.4 they added: or if type of the target is int
+ // and the operator is a shift operator...
+ //
+ if (source_type == TypeManager.int32_type &&
+ (b.Oper == Binary.Operator.LeftShift || b.Oper == Binary.Operator.RightShift))
+ return this;
+
Convert.Error_CannotImplicitConversion (loc, a.original_source.Type, target_type);
return null;
}
else\r
return false;\r
} else if (element is Property || element is Indexer ||\r
- element is InterfaceProperty || element is InterfaceIndexer) {\r
+ element is InterfaceProperty || element is InterfaceIndexer || element is InterfaceProperty.PropertyAccessor) {
if ((targets & AttributeTargets.Property) != 0)\r
return true;\r
else\r
return false;\r
- } else if (element is AssemblyBuilder){\r
+ } else if (element is AssemblyClass){
if ((targets & AttributeTargets.Assembly) != 0)\r
return true;\r
else\r
return false;\r
+ } else if (element is ModuleClass){
+ if ((targets & AttributeTargets.Module) != 0)
+ return true;
+ else
+ return false;
}\r
\r
return false;\r
if (asec.Attributes == null)\r
continue;\r
\r
- if (attr_target == "assembly" && !(builder is AssemblyBuilder))\r
- continue;\r
-\r
if (attr_target == "return" && !(builder is ParameterBuilder))\r
continue;\r
\r
return;\r
}\r
\r
- if (kind is Method || kind is Operator || kind is InterfaceMethod ||\r
+ if (kind is IAttributeSupport) {
+ if (attr_type == TypeManager.methodimpl_attr_type && a.ImplOptions == MethodImplOptions.InternalCall) {
+ ((MethodBuilder) builder).SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
+ }
+ else {
+ IAttributeSupport attributeSupport = kind as IAttributeSupport;
+ attributeSupport.SetCustomAttribute (cb);
+ }
+ }
+ else if (kind is Method || kind is Operator || kind is InterfaceMethod ||
+
kind is Accessor) {\r
if (attr_type == TypeManager.methodimpl_attr_type) {\r
if (a.ImplOptions == MethodImplOptions.InternalCall)\r
}\r
} else if (kind is Property || kind is Indexer ||\r
kind is InterfaceProperty || kind is InterfaceIndexer) {\r
+
+ if (builder is PropertyBuilder)
((PropertyBuilder) builder).SetCustomAttribute (cb);\r
+ //
+ // This is for the case we are setting attributes on
+ // the get and set accessors
+ //
+ else if (builder is MethodBuilder)
+ ((MethodBuilder) builder).SetCustomAttribute (cb);
} else if (kind is Event || kind is InterfaceEvent) {\r
((MyEventBuilder) builder).SetCustomAttribute (cb);\r
} else if (kind is ParameterBuilder) {\r
return false;\r
}\r
}\r
+
+ public interface IAttributeSupport {
+ void SetCustomAttribute (CustomAttributeBuilder customBuilder);
+ }
}\r
public AdditionResult AddProperty (Property prop)
{
AdditionResult res;
- string basename = prop.Name;
- string fullname = Name + "." + basename;
- if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
+ if ((res = AddProperty (prop, prop.Name)) != AdditionResult.Success)
return res;
+ if (prop.Get != null) {
+ if ((res = AddProperty (prop, "get_" + prop.Name)) != AdditionResult.Success)
+ return res;
+ }
+
+ if (prop.Set != null) {
+ if ((res = AddProperty (prop, "set_" + prop.Name)) != AdditionResult.Success)
+ return res;
+ }
+
if (properties == null)
properties = new ArrayList ();
properties.Insert (0, prop);
else
properties.Add (prop);
+
+ return AdditionResult.Success;
+ }
+
+ AdditionResult AddProperty (Property prop, string basename)
+ {
+ AdditionResult res;
+ string fullname = Name + "." + basename;
+
+ if ((res = IsValid (basename, fullname)) != AdditionResult.Success)
+ return res;
+
DefineName (fullname, prop);
return AdditionResult.Success;
return AdditionResult.Success;
}
- public AdditionResult AddIndexer (Indexer i)
+ public void AddIndexer (Indexer i)
{
if (indexers == null)
indexers = new ArrayList ();
indexers.Insert (0, i);
else
indexers.Add (i);
-
- return AdditionResult.Success;
}
public AdditionResult AddOperator (Operator op)
operators.Add (op);
+ string basename = op.Name;
+ string fullname = Name + "." + basename;
+ if (!defined_names.Contains (fullname))
+ {
+ DefineName (fullname, op);
+ }
return AdditionResult.Success;
}
void DefineDefaultConstructor (bool is_static)
{
Constructor c;
- int mods = 0;
- c = new Constructor (this, Basename, Parameters.EmptyReadOnlyParameters,
+ // The default constructor is public
+ // If the class is abstract, the default constructor is protected
+ // The default static constructor is private
+
+ int mods = Modifiers.PUBLIC;
+ if (is_static)
+ mods = Modifiers.STATIC | Modifiers.PRIVATE;
+ else if ((ModFlags & Modifiers.ABSTRACT) != 0)
+ mods = Modifiers.PROTECTED;
+
+ c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
new ConstructorBaseInitializer (
null, Parameters.EmptyReadOnlyParameters,
Location),
Location);
- if (is_static)
- mods = Modifiers.STATIC;
-
- //
- // If the class is abstract, the default constructor is protected
- //
- if ((ModFlags & Modifiers.ABSTRACT) != 0)
- mods |= Modifiers.PROTECTED;
-
- c.ModFlags = mods;
-
AddConstructor (c);
c.Block = new ToplevelBlock (null, Location);
return null;
}
- ModuleBuilder builder = CodeGen.ModuleBuilder;
+ ModuleBuilder builder = CodeGen.Module.Builder;
TypeBuilder = builder.DefineType (
Name, type_attributes, ptype, null);
{
if (constants != null)
foreach (Const con in constants)
- con.EmitConstant (this);
+ con.Emit (this);
return;
}
Modifiers.OVERRIDE |
Modifiers.ABSTRACT |
Modifiers.UNSAFE |
+ Modifiers.METHOD_YIELDS |
Modifiers.EXTERN;
//
public Method (DeclSpace ds, Expression return_type, int mod, string name,
Parameters parameters, Attributes attrs, Location l)
: base (ds, return_type, mod, AllowedModifiers, name, attrs, parameters, l)
- { }
+ {
+ }
public Method (GenericMethod generic, Expression return_type, int mod, string name,
Parameters parameters, Attributes attrs, Location l)
// The spec claims that static is not permitted, but
// my very own code has static constructors.
//
- public Constructor (DeclSpace ds, string name, Parameters args,
+ public Constructor (DeclSpace ds, string name, int mod, Parameters args,
ConstructorInitializer init, Location l)
- : base (ds, null, 0, AllowedModifiers, name, null, args, l)
+ : base (ds, null, mod, AllowedModifiers, name, null, args, l)
{
Initializer = init;
}
}
}
- public class Property : PropertyBase {
+ public class Property : PropertyBase, IIteratorContainer {
const int AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
Modifiers.ABSTRACT |
Modifiers.UNSAFE |
Modifiers.EXTERN |
+ Modifiers.METHOD_YIELDS |
Modifiers.VIRTUAL;
public Property (DeclSpace ds, Expression type, string name, int mod_flags,
parameters, ip, CallingConventions.Standard,
Get.OptAttributes, ModFlags, flags, false);
+ //
+ // Setup iterator if we are one
+ //
+ if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
+ IteratorHandler ih = new IteratorHandler (
+ "get", container, MemberType,
+ parameters, ip, ModFlags, Location);
+
+ Block new_block = ih.Setup (block);
+ if (new_block == null)
+ return false;
+ block = new_block;
+ }
+
if (!GetData.Define (container))
return false;
}
return true;
}
+
+ public void SetYields ()
+ {
+ ModFlags |= Modifiers.METHOD_YIELDS;
+ }
}
/// </summary>
Name = ShortName;
}
+ if (!CheckNameCollision (container))
+ return false;
+
if (!CheckBase (container))
return false;
return true;
}
+
+ bool CheckNameCollision (TypeContainer container) {
+ switch (VerifyName (container)){
+ case DeclSpace.AdditionResult.NameExists:
+ Report.Error (102, Location, "The container '{0}' already contains a definition for '{1}'", container.GetSignatureForError (), Name);
+ return false;
+
+ case DeclSpace.AdditionResult.Success:
+ return true;
+ }
+ throw new NotImplementedException ();
+ }
+
+ DeclSpace.AdditionResult VerifyName (TypeContainer container) {
+ if (!AddIndexer (container, container.Name + "." + Name))
+ return DeclSpace.AdditionResult.NameExists;
+
+ if (Get != null) {
+ if (!AddIndexer (container, container.Name + ".get_" + Name))
+ return DeclSpace.AdditionResult.NameExists;
+ }
+
+ if (Set != null) {
+ if (!AddIndexer (container, container.Name + ".set_" + Name))
+ return DeclSpace.AdditionResult.NameExists;
+ }
+ return DeclSpace.AdditionResult.Success;
+ }
+
+ bool AddIndexer (TypeContainer container, string fullname)
+ {
+ object value = container.GetDefinition (fullname);
+
+ if (value != null) {
+ return value.GetType () != GetType () ? false : true;
+ }
+
+ container.DefineName (fullname, this);
+ return true;
+ }
+
+ public override string GetSignatureForError () {
+ return TypeManager.CSharpSignature (PropertyBuilder, true);
+ }
}
- public class Operator : MemberBase {
+ public class Operator : MemberBase, IIteratorContainer {
const int AllowedModifiers =
Modifiers.PUBLIC |
: base (ret_type, mod_flags, AllowedModifiers, Modifiers.PUBLIC, "", attrs, loc)
{
OperatorType = type;
+ Name = "op_" + OperatorType;
ReturnType = ret_type;
FirstArgType = arg1type;
FirstArgName = arg1name;
new Parameters (param_list, null, Location),
OptAttributes, Location);
+ OperatorMethod.Block = Block;
OperatorMethod.IsOperator = true;
OperatorMethod.Define (container);
if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
return;
- OperatorMethod.Block = Block;
OperatorMethod.Emit (container);
Block = null;
}
GetName (OperatorType),
param_types [0], param_types [1]);
}
+
+ public void SetYields ()
+ {
+ ModFlags |= Modifiers.METHOD_YIELDS;
+ }
}
//
// If only accessible to the defining assembly or
if (prot == MethodAttributes.FamANDAssem ||
prot == MethodAttributes.Assembly){
- if (m.DeclaringType.Assembly == CodeGen.AssemblyBuilder)
- return true;
- else
- return false;
+ return m.DeclaringType.Assembly == CodeGen.Assembly.Builder;
}
// Anything else (FamOrAssembly and Public) is fine
/// </summary>
public class CodeGen {
static AppDomain current_domain;
- public static AssemblyBuilder AssemblyBuilder;
- public static ModuleBuilder ModuleBuilder;
-
static public SymbolWriter SymbolWriter;
+ public static AssemblyClass Assembly;
+ public static ModuleClass Module;
+
+ static CodeGen ()
+ {
+ Assembly = new AssemblyClass ();
+ Module = new ModuleClass (RootContext.Unsafe);
+ }
+
public static string Basename (string name)
{
int pos = name.LastIndexOf ('/');
//
static void InitializeSymbolWriter ()
{
- SymbolWriter = SymbolWriter.GetSymbolWriter (ModuleBuilder);
+ SymbolWriter = SymbolWriter.GetSymbolWriter (Module.Builder);
//
// If we got an ISymbolWriter instance, initialize it.
an.Name = Path.GetFileNameWithoutExtension (name);
current_domain = AppDomain.CurrentDomain;
- AssemblyBuilder = current_domain.DefineDynamicAssembly (
+ Assembly.Builder = current_domain.DefineDynamicAssembly (
an, AssemblyBuilderAccess.Save, Dirname (name));
//
// If the third argument is true, the ModuleBuilder will dynamically
// load the default symbol writer.
//
- ModuleBuilder = AssemblyBuilder.DefineDynamicModule (
+ Module.Builder = Assembly.Builder.DefineDynamicModule (
Basename (name), Basename (output), want_debugging_support);
if (want_debugging_support)
static public void Save (string name)
{
try {
- AssemblyBuilder.Save (Basename (name));
+ Assembly.Builder.Save (Basename (name));
} catch (System.IO.IOException io){
Report.Error (16, "Could not write to file `"+name+"', cause: " + io.Message);
}
else
ig.Emit (OpCodes.Ldfld, fb);
}
+
+ public void EmitCall (MethodInfo mi)
+ {
+ // FIXME : we should handle a call like tostring
+ // here, where boxing is needed. However, we will
+ // never encounter that with the current usage.
+
+ bool value_type_call;
+ EmitThis ();
+ if (fb == null) {
+ value_type_call = local.LocalType.IsValueType;
+
+ if (value_type_call)
+ ig.Emit (OpCodes.Ldloca, local);
+ else
+ ig.Emit (OpCodes.Ldloc, local);
+ } else {
+ value_type_call = fb.FieldType.IsValueType;
+
+ if (value_type_call)
+ ig.Emit (OpCodes.Ldflda, fb);
+ else
+ ig.Emit (OpCodes.Ldfld, fb);
+ }
+
+ ig.Emit (value_type_call ? OpCodes.Call : OpCodes.Callvirt, mi);
+ }
}
/// <summary>
return my_this;
}
}
+
+
+ public abstract class CommonAssemblyModulClass: IAttributeSupport {
+ Hashtable m_attributes;
+
+ protected CommonAssemblyModulClass ()
+ {
+ m_attributes = new Hashtable ();
+ }
+
+ //
+ // Adds a global attribute that was declared in `container',
+ // the attribute is in `attr', and it was defined at `loc'
+ //
+ public void AddAttribute (TypeContainer container, AttributeSection attr)
+ {
+ NamespaceEntry ns = container.NamespaceEntry;
+ Attributes a = (Attributes) m_attributes [ns];
+
+ if (a == null) {
+ m_attributes [ns] = new Attributes (attr);
+ return;
+ }
+
+ a.AddAttributeSection (attr);
+ }
+
+ public virtual void Emit ()
+ {
+ if (m_attributes.Count < 1)
+ return;
+
+ TypeContainer dummy = new TypeContainer ();
+ EmitContext temp_ec = new EmitContext (dummy, Mono.CSharp.Location.Null, null, null, 0, false);
+
+ foreach (DictionaryEntry de in m_attributes)
+ {
+ NamespaceEntry ns = (NamespaceEntry) de.Key;
+ Attributes attrs = (Attributes) de.Value;
+
+ dummy.NamespaceEntry = ns;
+ Attribute.ApplyAttributes (temp_ec, null, this, attrs);
+ }
+ }
+
+ #region IAttributeSupport Members
+ public abstract void SetCustomAttribute(CustomAttributeBuilder customBuilder);
+ #endregion
+
+ }
+
+
+ public class AssemblyClass: CommonAssemblyModulClass {
+ // TODO: make it private and move all builder based methods here
+ public AssemblyBuilder Builder;
+
+ bool m_is_cls_compliant;
+
+ public AssemblyClass (): base ()
+ {
+ m_is_cls_compliant = false;
+ }
+
+ public bool IsClsCompliant {
+ get {
+ return m_is_cls_compliant;
+ }
+ }
+
+ public override void SetCustomAttribute(CustomAttributeBuilder customBuilder)
+ {
+ Builder.SetCustomAttribute (customBuilder);
+ }
+ }
+
+ public class ModuleClass: CommonAssemblyModulClass {
+ // TODO: make it private and move all builder based methods here
+ public ModuleBuilder Builder;
+
+ bool m_module_is_unsafe;
+
+ public ModuleClass (bool is_unsafe)
+ {
+ m_module_is_unsafe = is_unsafe;
+ }
+
+ public override void Emit ()
+ {
+ base.Emit ();
+
+ if (!m_module_is_unsafe)
+ return;
+
+ if (TypeManager.unverifiable_code_ctor == null) {
+ Console.WriteLine ("Internal error ! Cannot set unverifiable code attribute.");
+ return;
+ }
+
+ SetCustomAttribute (new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor, new object [0]));
+ }
+
+ public override void SetCustomAttribute(CustomAttributeBuilder customBuilder)
+ {
+ Builder.SetCustomAttribute (customBuilder);
+ }
+ }
+
}
using System.Reflection.Emit;
using System.Collections;
- public class Const : MemberBase {
- public Expression ConstantType;
+ public class Const : FieldBase {
public Expression Expr;
- public FieldBuilder FieldBuilder;
EmitContext const_ec;
object ConstantValue = null;
public Const (Expression constant_type, string name, Expression expr, int mod_flags,
Attributes attrs, Location loc)
- : base (constant_type, mod_flags, AllowedModifiers, Modifiers.PRIVATE, name, attrs, loc)
+ : base (constant_type, mod_flags, AllowedModifiers, name, null, attrs, loc)
{
- ConstantType = constant_type;
- Name = name;
Expr = expr;
}
/// </summary>
public override bool Define (TypeContainer parent)
{
- type = parent.ResolveType (ConstantType, false, Location);
+ type = parent.ResolveType (Type, false, Location);
if (type == null)
return false;
/// <summary>
/// Emits the field value by evaluating the expression
/// </summary>
- public void EmitConstant (TypeContainer parent)
+ public void Emit (TypeContainer parent)
{
LookupConstantValue ();
%token WHERE
%token WHILE
-/* v2 tokens */
-%token YIELD
-
/* C# keywords which are not really keywords */
%token GET "get"
%token SET "set"
if (attrs != null) {
foreach (AttributeSection asec in attrs.AttributeSections)
if (asec.Target == "assembly")
- RootContext.AddGlobalAttributeSection (current_container, asec);
+ CodeGen.Assembly.AddAttribute (current_container, asec);
else
Report.Error(1518, Lexer.Location,
"Attributes cannot be applied to namespaces."
AttributeSection sect = (AttributeSection) $1;
if (sect.Target == "assembly") {
- RootContext.AddGlobalAttributeSection (current_container, sect);
+ CodeGen.Assembly.AddAttribute (current_container, sect);
+ $$ = null;
+ }
+ else if (sect.Target == "module") {
+ CodeGen.Module.AddAttribute (current_container, sect);
$$ = null;
}
else
AttributeSection sect = (AttributeSection) $2;
if (sect.Target == "assembly") {
- RootContext.AddGlobalAttributeSection (current_container, sect);
- } else {
+ CodeGen.Assembly.AddAttribute (current_container, sect);
+ }
+ else if (sect.Target == "module") {
+ CodeGen.Module.AddAttribute (current_container, sect);
+ }
+ else {
if (attrs == null)
attrs = new Attributes (sect);
else
lexer.PropertyParsing = true;
$$ = lexer.Location;
+
+ iterator_container = SimpleIteratorContainer.GetSimple ();
}
accessor_declarations
{
Location loc = (Location) $6;
prop = new Property (current_container, (Expression) $3, (string) $4, (int) $2,
get_block, set_block, (Attributes) $1, loc);
+ if (SimpleIteratorContainer.Simple.Yields)
+ prop.SetYields ();
CheckDef (current_container.AddProperty (prop), prop.Name, loc);
implicit_value_parameter_type = null;
+ iterator_container = null;
}
;
type IDENTIFIER
OPEN_BRACE
{ lexer.PropertyParsing = true; }
- interface_accesors
+ interface_accessors
{ lexer.PropertyParsing = false; }
CLOSE_BRACE
{
- int gs = (int) $7;
+ InterfaceAccessorInfo pinfo = (InterfaceAccessorInfo) $7;
$$ = new InterfaceProperty ((Expression) $3, (string) $4, (bool) $2,
- (gs & 1) == 1, (gs & 2) == 2, (Attributes) $1,
+ pinfo.has_get, pinfo.has_set, (Attributes) $1,
+ pinfo.get_attrs, pinfo.set_attrs,
lexer.Location);
}
| opt_attributes
}
;
-interface_accesors
- : opt_attributes GET SEMICOLON { $$ = 1; }
- | opt_attributes SET SEMICOLON { $$ = 2; }
+interface_accessors
+ : opt_attributes GET SEMICOLON { $$ = new InterfaceAccessorInfo (true, false, (Attributes) $1, null); }
+ | opt_attributes SET SEMICOLON { $$ = new InterfaceAccessorInfo (false, true, null, (Attributes) $1); }
| opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON
- { $$ = 3; }
+ { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $1, (Attributes) $3); }
| opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON
- { $$ = 3; }
+ { $$ = new InterfaceAccessorInfo (true, true, (Attributes) $3, (Attributes) $1); }
;
interface_event_declaration
OPEN_BRACKET formal_parameter_list CLOSE_BRACKET
OPEN_BRACE
{ lexer.PropertyParsing = true; }
- interface_accesors
+ interface_accessors
{ lexer.PropertyParsing = false; }
CLOSE_BRACE
{
- int a_flags = (int) $10;
+ InterfaceAccessorInfo info = (InterfaceAccessorInfo) $10;
- bool do_get = (a_flags & 1) == 1;
- bool do_set = (a_flags & 2) == 2;
+ bool do_get = info.has_get;
+ bool do_set = info.has_set;
$$ = new InterfaceIndexer ((Expression) $3, (Parameters) $6, do_get, do_set,
- (bool) $2, (Attributes) $1, lexer.Location);
+ (bool) $2, (Attributes) $1, (Attributes) info.get_attrs,
+ (Attributes) info.set_attrs, lexer.Location);
}
;
operator_declaration
- : opt_attributes opt_modifiers operator_declarator operator_body
+ : opt_attributes opt_modifiers operator_declarator
+ {
+ iterator_container = SimpleIteratorContainer.GetSimple ();
+ }
+ operator_body
{
OperatorDeclaration decl = (OperatorDeclaration) $3;
Operator op = new Operator (decl.optype, decl.ret_type, (int) $2, decl.arg1type, decl.arg1name,
- decl.arg2type, decl.arg2name, (Block) $4, (Attributes) $1, decl.location);
+ decl.arg2type, decl.arg2name, (Block) $5, (Attributes) $1, decl.location);
+
+ if (SimpleIteratorContainer.Simple.Yields)
+ op.SetYields ();
// Note again, checking is done in semantic analysis
current_container.AddOperator (op);
current_local_parameters = null;
+ iterator_container = null;
}
;
opt_constructor_initializer
{
Location l = (Location) oob_stack.Pop ();
- $$ = new Constructor (current_container, (string) $1, (Parameters) $3,
+ $$ = new Constructor (current_container, (string) $1, 0, (Parameters) $3,
(ConstructorInitializer) $6, l);
}
;
;
yield_statement
- : YIELD RETURN expression SEMICOLON
+ : IDENTIFIER RETURN expression SEMICOLON
{
+ string s = (string) $1;
+ if (s != "yield"){
+ Report.Error (1003, lexer.Location, "; expected");
+ $$ = null;
+ }
+ if (!RootContext.V2){
+ Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode");
+ $$ = null;
+ }
if (iterator_container == null){
Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
$$ = null;
$$ = new Yield ((Expression) $3, lexer.Location);
}
}
- | YIELD expression SEMICOLON
+ | IDENTIFIER BREAK SEMICOLON
{
- if (iterator_container == null){
- Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+ string s = (string) $1;
+ if (s != "yield"){
+ Report.Error (1003, lexer.Location, "; expected");
+ $$ = null;
+ }
+ if (!RootContext.V2){
+ Report.Error (-222, lexer.Location, "yield statement only available in C# 2.0 mode");
$$ = null;
- } else {
- iterator_container.SetYields ();
- $$ = new Yield ((Expression) $2, lexer.Location);
}
- }
- | YIELD BREAK SEMICOLON
- {
if (iterator_container == null){
Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
$$ = null;
}
}
+/// <summary>
+/// Used to pass around interface property information
+/// </summary>
+public class InterfaceAccessorInfo {
+
+ public bool has_get;
+ public bool has_set;
+ public Attributes get_attrs;
+ public Attributes set_attrs;
+
+ public InterfaceAccessorInfo (bool has_get, bool has_set,
+ Attributes get_attrs, Attributes set_attrs)
+ {
+ this.has_get = has_get;
+ this.has_set = has_set;
+ this.get_attrs = get_attrs;
+ this.set_attrs = set_attrs;
+ }
+}
+
+
// <summary>
// A class used to hold info about an indexer declarator
// </summary>
}
}
+//
+// We use this when we do not have an object in advance that is an IIteratorContainer
+//
+public class SimpleIteratorContainer : IIteratorContainer {
+ public bool Yields;
+
+ public static SimpleIteratorContainer Simple = new SimpleIteratorContainer ();
+
+ //
+ // Reset and return
+ //
+ public static SimpleIteratorContainer GetSimple () {
+ Simple.Yields = false;
+ return Simple;
+ }
+
+ public void SetYields () { Yields = true; }
+}
+
// <summary>
// A class used to hold info about an operator declarator
// </summary>
{
switch (a) {
- case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
+ case "assembly" : case "module" : case "field" : case "method" : case "param" : case "property" : case "type" :
return;
default :
AddKeyword ("volatile", Token.VOLATILE);\r
AddKeyword ("where", Token.WHERE);\r
AddKeyword ("while", Token.WHILE);\r
-\r
- if (RootContext.V2){\r
- AddKeyword ("__yield", Token.YIELD);\r
- AddKeyword ("yield", Token.YIELD);\r
- }\r
}\r
\r
//\r
tokens_seen = false;\r
arg = "";\r
static_cmd_arg.Length = 0;\r
+\r
+ // skip over white space\r
+ while ((c = getChar ()) != -1 && (c != '\n') && ((c == '\r') || (c == ' ') || (c == '\t')))\r
+ ;\r
\r
- while ((c = getChar ()) != -1 && (c != '\n') && (c != ' ') && (c != '\t') && (c != '\r')){\r
+ while ((c != -1) && (c != '\n') && (c != ' ') && (c != '\t') && (c != '\r')){\r
static_cmd_arg.Append ((char) c);\r
+ c = getChar ();\r
}\r
\r
cmd = static_cmd_arg.ToString ();\r
ref_name = file_name;\r
Location.Push (ref_name);\r
return true;\r
+ } else if (arg == "hidden"){\r
+ //\r
+ // We ignore #line hidden\r
+ //\r
+ return true;\r
}\r
\r
try {\r
val = null;\r
// optimization: eliminate col and implement #directive semantic correctly.\r
for (;(c = getChar ()) != -1; col++) {\r
- if (c == ' ' || c == '\t' || c == '\f' || c == '\v' || c == '\r' || c == 0xa0){\r
- \r
- if (c == '\t')\r
- col = (((col + 8) / 8) * 8) - 1;\r
+ if (c == ' ')\r
+ continue;\r
+ \r
+ if (c == '\t') {\r
+ col = (((col + 8) / 8) * 8) - 1;\r
+ continue;\r
+ }\r
+ \r
+ if (c == ' ' || c == '\f' || c == '\v' || c == 0xa0)\r
+ continue;\r
+\r
+ if (c == '\r') {\r
+ if (peekChar () == '\n')\r
+ getChar ();\r
+\r
+ line++;\r
+ ref_line++;\r
+ col = 0;\r
+ any_token_seen |= tokens_seen;\r
+ tokens_seen = false;\r
continue;\r
}\r
\r
public abstract bool Define (TypeContainer parent);
+ //
+ // Returns full member name for error message
+ //
+ public virtual string GetSignatureForError () {
+ return Name;
+ }
+
public Attributes OptAttributes
{
get {
/// associates it with the object @o. Note that for
/// methods this will just point to the first method. o
/// </summary>
- protected void DefineName (string name, object o)
+ public void DefineName (string name, object o)
{
defined_names.Add (name, o);
if (TypeManager.NamespaceClash (Name, Location))\r
return null;\r
\r
- ModuleBuilder builder = CodeGen.ModuleBuilder;\r
+ ModuleBuilder builder = CodeGen.Module.Builder;
\r
TypeBuilder = builder.DefineType (\r
Name, attr, TypeManager.multicast_delegate_type);\r
}\r
\r
ReturnType = ResolveTypeExpr (ReturnType, false, Location);\r
+ if (ReturnType == null)
+ return false;
+
ret_type = ReturnType.Type;\r
if (ret_type == null)\r
return false;\r
\r
public DelegateCreation () {}\r
\r
- public static void Error_NoMatchingMethodForDelegate (MethodGroupExpr mg, Type t, MethodBase method, Location loc)\r
+ public static void Error_NoMatchingMethodForDelegate (EmitContext ec, MethodGroupExpr mg, Type type, Location loc)
{\r
string method_desc;\r
\r
method_desc = mg.Methods [0].Name;\r
else\r
method_desc = Invocation.FullMethodDesc (mg.Methods [0]);\r
-\r
- ParameterData param = Invocation.GetParameterData (method);\r
- string delegate_desc = Delegate.FullDelegateDesc (t, method, param);\r
+
+ Expression invoke_method = Expression.MemberLookup (
+ ec, type, "Invoke", MemberTypes.Method,
+ Expression.AllBindingFlags, loc);
+ MethodBase method = ((MethodGroupExpr) invoke_method).Methods [0];
+ ParameterData param = Invocation.GetParameterData (method);\r
+ string delegate_desc = Delegate.FullDelegateDesc (type, method, param);
\r
Report.Error (123, loc, "Method '" + method_desc + "' does not " +\r
"match delegate '" + delegate_desc + "'");\r
}\r
\r
if (delegate_method == null) {\r
- Error_NoMatchingMethodForDelegate (mg, type, delegate_method, loc);\r
+ Error_NoMatchingMethodForDelegate (ec, mg, type, loc);
return null;\r
}\r
\r
try {
try {
- m = (Module)adder_method.Invoke (CodeGen.AssemblyBuilder, new object [] { module });
+ m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { module });
}
catch (TargetInvocationException ex) {
throw ex.InnerException;
try {
try {
- m = (Module)adder_method.Invoke (CodeGen.AssemblyBuilder, new object [] { full_path });
+ m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { full_path });
}
catch (TargetInvocationException ex) {
throw ex.InnerException;
Environment.Exit (1);
}
- module_only.SetValue (CodeGen.AssemblyBuilder, true, null);
+ module_only.SetValue (CodeGen.Assembly.Builder, true, null);
}
- TypeManager.AddModule (CodeGen.ModuleBuilder);
+ TypeManager.AddModule (CodeGen.Module.Builder);
if (modules.Count > 0) {
MethodInfo adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
return false;
}
- CodeGen.AssemblyBuilder.SetEntryPoint (ep, k);
+ CodeGen.Assembly.Builder.SetEntryPoint (ep, k);
} else if (RootContext.MainClass != null) {
Report.Error (2017, "Can not specify -main: when building module or library");
}
} else
file = res = spec;
- CodeGen.AssemblyBuilder.AddResourceFile (res, file);
+ CodeGen.Assembly.Builder.AddResourceFile (res, file);
}
}
margs [0] = margs [1] = spec;
if (File.Exists ((string) margs [1]))
- embed_res.Invoke (CodeGen.AssemblyBuilder, margs);
+ embed_res.Invoke (CodeGen.Assembly.Builder, margs);
else {
Report.Error (1566, "Can not find the resource " + margs [1]);
}
// Add Win32 resources
//
- CodeGen.AssemblyBuilder.DefineVersionInfoResource ();
+ CodeGen.Assembly.Builder.DefineVersionInfoResource ();
if (win32ResourceFile != null) {
try {
- CodeGen.AssemblyBuilder.DefineUnmanagedResource (win32ResourceFile);
+ CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
}
catch (ArgumentException) {
Report.Warning (0, new Location (-1), "Cannot embed win32 resources on this runtime: try the Mono runtime instead.");
if (define_icon == null) {
Report.Warning (0, new Location (-1), "Cannot embed icon resource on this runtime: try the Mono runtime instead.");
}
- define_icon.Invoke (CodeGen.AssemblyBuilder, new object [] { win32IconFile });
+ define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
}
if (Report.Errors > 0)
if (TypeManager.NamespaceClash (Name, Location))
return null;
- ModuleBuilder builder = CodeGen.ModuleBuilder;
+ ModuleBuilder builder = CodeGen.Module.Builder;
TypeBuilder = builder.DefineType (Name, attr, TypeManager.enum_type);
} else {
// Author:
// Miguel de Icaza (miguel@ximian.com)
//
-// (C) 2001 Ximian, Inc.
-//
+// (C) 2001, 2002, 2003 Ximian, Inc.
+// (C) 2003, 2004 Novell, Inc.
//
#define USE_OLD
Error_OperatorCannotBeApplied (loc, OperName (oper), left.Type, right.Type);
}
- static bool is_32_or_64 (Type t)
- {
- return (t == TypeManager.int32_type || t == TypeManager.uint32_type ||
- t == TypeManager.int64_type || t == TypeManager.uint64_type);
- }
-
static bool is_unsigned (Type t)
{
return (t == TypeManager.uint32_type || t == TypeManager.uint64_type ||
else
return false;
}
+
+ Expression Make32or64 (EmitContext ec, Expression e)
+ {
+ Type t= e.Type;
+
+ if (t == TypeManager.int32_type || t == TypeManager.uint32_type ||
+ t == TypeManager.int64_type || t == TypeManager.uint64_type)
+ return e;
+ Expression ee = Convert.ImplicitConversion (ec, e, TypeManager.int32_type, loc);
+ if (ee != null)
+ return ee;
+ ee = Convert.ImplicitConversion (ec, e, TypeManager.uint32_type, loc);
+ if (ee != null)
+ return ee;
+ ee = Convert.ImplicitConversion (ec, e, TypeManager.int64_type, loc);
+ if (ee != null)
+ return ee;
+ ee = Convert.ImplicitConversion (ec, e, TypeManager.uint64_type, loc);
+ if (ee != null)
+ return ee;
+ return null;
+ }
Expression CheckShiftArguments (EmitContext ec)
{
return new PointerArithmetic (
false, left, right, TypeManager.int64_type,
loc);
- } else if (is_32_or_64 (r))
- return new PointerArithmetic (
- oper == Operator.Addition, left, right, l, loc);
- } else if (r.IsPointer && is_32_or_64 (l) && oper == Operator.Addition)
- return new PointerArithmetic (
- true, right, left, r, loc);
+ } else {
+ Expression t = Make32or64 (ec, right);
+ if (t != null)
+ return new PointerArithmetic (oper == Operator.Addition, left, t, l, loc);
+ }
+ } else if (r.IsPointer && oper == Operator.Addition){
+ Expression t = Make32or64 (ec, left);
+ if (t != null)
+ return new PointerArithmetic (true, right, t, r, loc);
+ }
}
//
eclass = ExprClass.Value;
return this;
} else {
- ModuleBuilder mb = CodeGen.ModuleBuilder;
+ ModuleBuilder mb = CodeGen.Module.Builder;
ArrayList args = new ArrayList ();
if (arguments != null) {
if (dims != 1){
Type [] args;
ModuleBuilder mb = null;
- mb = CodeGen.ModuleBuilder;
+ mb = CodeGen.Module.Builder;
args = new Type [dims + 1];
int j;
MethodInfo FetchGetMethod ()
{
- ModuleBuilder mb = CodeGen.ModuleBuilder;
+ ModuleBuilder mb = CodeGen.Module.Builder;
int arg_count = ea.Arguments.Count;
Type [] args = new Type [arg_count];
MethodInfo get;
MethodInfo FetchAddressMethod ()
{
- ModuleBuilder mb = CodeGen.ModuleBuilder;
+ ModuleBuilder mb = CodeGen.Module.Builder;
int arg_count = ea.Arguments.Count;
Type [] args = new Type [arg_count];
MethodInfo address;
if (rank == 1)
EmitStoreOpcode (ig, t);
else {
- ModuleBuilder mb = CodeGen.ModuleBuilder;
+ ModuleBuilder mb = CodeGen.Module.Builder;
int arg_count = ea.Arguments.Count;
Type [] args = new Type [arg_count + 1];
MethodInfo set;
MethodAttributes.Virtual;
ArrayList bases;
+ Type[] baseTypes;
ArrayList defined_method;
ArrayList defined_indexer;
members.Add (eb);
}
- if (((bf & BindingFlags.DeclaredOnly) == 0) && (TypeBuilder.BaseType != null)) {
- MemberList parent_mi;
-
- parent_mi = TypeContainer.FindMembers (
- TypeBuilder.BaseType, mt, bf, filter, criteria);
-
- members.AddRange (parent_mi);
+ if (((bf & BindingFlags.DeclaredOnly) == 0) && (baseTypes != null)) {
+ foreach (Type baseType in baseTypes) {
+ members.AddRange (TypeContainer.FindMembers (baseType, mt, bf, filter, criteria));
+ }
}
return new MemberList (members);
//
void PopulateMethod (TypeContainer parent, DeclSpace decl_space, InterfaceMethod im)
{
+ if (im.ReturnType == null)
+ return;
+
Type return_type = im.ReturnType.Type;
if (return_type == null)
return_type = this.ResolveType (im.ReturnType, false, im.Location);
// removing the old code here.
//
- im.Builder = mb;
+ im.SetBuilder (mb);
}
void PopulateProperty (TypeContainer parent, DeclSpace decl_space, InterfaceProperty ip)
{
PropertyBuilder pb;
- MethodBuilder get = null, set = null;
- ip.Type = this.ResolveTypeExpr (ip.Type, false, ip.Location);
- if (ip.Type == null)
+
+ ip.ReturnType = this.ResolveTypeExpr (ip.ReturnType, false, ip.Location);
+ if (ip.ReturnType == null)
return;
- Type prop_type = ip.Type.Type;
+ Type prop_type = ip.ReturnType.Type;
Type [] setter_args = new Type [1];
if (prop_type == null)
ip.Name, PropertyAttributes.None,
prop_type, null);
+ MethodBuilder get = null, set = null;
+
if (ip.HasGet){
get = TypeBuilder.DefineMethod (
"get_" + ip.Name, property_attributes ,
// HACK because System.Reflection.Emit is lame
//
Parameter [] parms = new Parameter [1];
- parms [0] = new Parameter (ip.Type, "value", Parameter.Modifier.NONE, null);
+ parms [0] = new Parameter (ip.ReturnType, "value", Parameter.Modifier.NONE, null);
InternalParameters ipp = new InternalParameters (
this, new Parameters (parms, null, Location.Null));
TypeManager.RegisterProperty (pb, get, set);
property_builders.Add (pb);
- ip.Builder = pb;
+ ip.SetBuilders (pb, get, set);
}
//
//
MyEventBuilder eb;
MethodBuilder add = null, remove = null;
- ie.Type = this.ResolveTypeExpr (ie.Type, false, ie.Location);
- if (ie.Type == null)
+ ie.ReturnType = this.ResolveTypeExpr (ie.ReturnType, false, ie.Location);
+ if (ie.ReturnType == null)
return;
- Type event_type = ie.Type.Type;
+ Type event_type = ie.ReturnType.Type;
if (event_type == null)
return;
eb.SetRemoveOnMethod (remove);
Parameter [] parms = new Parameter [1];
- parms [0] = new Parameter (ie.Type, "value", Parameter.Modifier.NONE, null);
+ parms [0] = new Parameter (ie.ReturnType, "value", Parameter.Modifier.NONE, null);
InternalParameters ip = new InternalParameters (
this, new Parameters (parms, null, Location.Null));
TypeManager.RegisterEvent (eb, add, remove);
event_builders.Add (eb);
- ie.Builder = eb;
+ ie.SetBuilder (eb);
}
//
void PopulateIndexer (TypeContainer parent, DeclSpace decl_space, InterfaceIndexer ii)
{
PropertyBuilder pb;
- ii.Type = this.ResolveTypeExpr (ii.Type, false, ii.Location);
- if (ii.Type == null)
+ ii.ReturnType = this.ResolveTypeExpr (ii.ReturnType, false, ii.Location);
+ if (ii ==null || ii.ReturnType == null)
return;
- Type prop_type = ii.Type.Type;
+ Type prop_type = ii.ReturnType.Type;
Type [] arg_types = ii.ParameterTypes (this);
Type [] value_arg_types;
pv = new Parameter [p.Length + 1];
p.CopyTo (pv, 0);
- pv [p.Length] = new Parameter (ii.Type, "value", Parameter.Modifier.NONE, null);
+ pv [p.Length] = new Parameter (ii.ReturnType, "value", Parameter.Modifier.NONE, null);
Parameters value_params = new Parameters (pv, null, Location.Null);
value_params.GetParameterInfo (decl_space);
property_builders.Add (pb);
- ii.Builder = pb;
+ ii.SetBuilders (pb, get_item, set_item);
}
/// <summary>
if (TypeManager.NamespaceClash (Name, Location))
return null;
- ModuleBuilder builder = CodeGen.ModuleBuilder;
+ ModuleBuilder builder = CodeGen.Module.Builder;
TypeBuilder = builder.DefineType (
Name,
}
if (ifaces != null) {
- foreach (TypeExpr iface in ifaces) {
- Type itype = iface.ResolveType (ec);
+ baseTypes = new Type[ifaces.Length];
+ for (int i = 0; i < ifaces.Length; ++i) {
+ Type itype = ifaces [i].ResolveType (ec);
TypeBuilder.AddInterfaceImplementation (itype);
+ baseTypes [i] = itype;
}
}
/// <summary>
/// Applies all the attributes.
/// </summary>
- public void Emit (TypeContainer tc)
- {
+ public void Emit (TypeContainer tc) {
if (OptAttributes != null) {
- EmitContext ec = new EmitContext (tc, this, Location, null, null,
- ModFlags, false);
+ EmitContext ec = new EmitContext (tc, this, Location, null, null, ModFlags, false);
Attribute.ApplyAttributes (ec, TypeBuilder, this, OptAttributes);
}
- // Now emit attributes for each interface member
- if (defined_method != null) {
- foreach (InterfaceMethod im in defined_method) {
- EmitContext ec = new EmitContext (tc, this, Location, null,
- im.ReturnType.Type, ModFlags, false);
-
- MethodCore.LabelParameters (ec, im.Builder,
- im.Parameters,
- im.OptAttributes,
- Location);
-
- if (im.OptAttributes != null)
- Attribute.ApplyAttributes (ec, im.Builder,
- im, im.OptAttributes);
-
- }
- }
-
- if (defined_properties != null) {
- foreach (InterfaceProperty ip in defined_properties) {
- EmitContext ec = new EmitContext (tc, this, Location, null,
- null, ModFlags, false);
-
- if (ip.OptAttributes != null)
- Attribute.ApplyAttributes (ec, ip.Builder, ip, ip.OptAttributes);
- }
- }
+ EmitSubType (tc, defined_method);
+ EmitSubType (tc, defined_properties);
+ EmitSubType (tc, defined_indexer);
+ EmitSubType (tc, defined_events);
+ }
- if (defined_events != null) {
- foreach (InterfaceEvent ie in defined_events) {
- EmitContext ec = new EmitContext (tc, this, Location, null,
- null, ModFlags, false);
+ void EmitSubType (TypeContainer tc, ArrayList subType) {
+ if (subType == null)
+ return;
- if (ie.OptAttributes != null)
- Attribute.ApplyAttributes (ec, ie.Builder, ie, ie.OptAttributes);
- }
+ foreach (InterfaceMemberBase imb in subType) {
+ //TODO: set it somewhere earlier
+ imb.ModFlags = ModFlags;
+ imb.Emit (tc, this);
}
}
BindingFlags.Public | BindingFlags.Instance,
Location.Null);
- if (!(ml is MethodGroupExpr)) {
- Console.WriteLine ("Internal error !!!!");
- return null;
- }
-
MethodGroupExpr mg = (MethodGroupExpr) ml;
MethodBase constructor = mg.Methods [0];
}
}
- public class InterfaceMemberBase {
- public readonly string Name;
+ public abstract class InterfaceMemberBase: MemberCore, IAttributeSupport {
public readonly bool IsNew;
- public Attributes OptAttributes;
+ // Why is not readonly
+ public Expression ReturnType;
- public InterfaceMemberBase (string name, bool is_new, Attributes attrs)
+ public InterfaceMemberBase (Expression type, string name, bool is_new, Attributes attrs, Location loc):
+ base (name, attrs, loc)
{
- Name = name;
+ ReturnType = type;
IsNew = is_new;
- OptAttributes = attrs;
}
- }
+
+ public virtual EmitContext Emit (TypeContainer tc, DeclSpace ds) {
+ EmitContext ec = null;
+ if (OptAttributes != null) {
+ ec = new EmitContext (tc, ds, Location, null, null, ModFlags, false);
+
+ Attribute.ApplyAttributes (ec, null, this, OptAttributes);
+ }
+
+ return ec;
+ }
+
+ #region IAttributeSupport Members
+ public abstract void SetCustomAttribute (CustomAttributeBuilder customBuilder);
+ #endregion
- public class InterfaceProperty : InterfaceMemberBase {
+ public override bool Define (TypeContainer parent) {
+ throw new NotImplementedException ();
+ }
+ }
+
+ abstract public class InterfaceSetGetBase: InterfaceMemberBase
+ {
+ internal sealed class PropertyAccessor: IAttributeSupport
+ {
+ Attributes m_attrs;
+ MethodBuilder m_builder;
+
+ public PropertyAccessor (Attributes attrs) {
+ m_attrs = attrs;
+ }
+
+ public MethodBuilder Builder {
+ set {
+ m_builder = value;
+ }
+ }
+
+ public void Emit (EmitContext ec) {
+ if (m_attrs != null) {
+ Attribute.ApplyAttributes (ec, this, this, m_attrs);
+ }
+ }
+
+ public void SetCustomAttribute (CustomAttributeBuilder customAttribute) {
+ m_builder.SetCustomAttribute (customAttribute);
+ }
+ }
+
+
+ PropertyAccessor m_get;
+ PropertyAccessor m_set;
+ protected PropertyBuilder Builder;
+
public readonly bool HasSet;
public readonly bool HasGet;
- public readonly Location Location;
- public Expression Type;
- public PropertyBuilder Builder;
- public InterfaceProperty (Expression type, string name,
- bool is_new, bool has_get, bool has_set,
- Attributes attrs, Location loc)
- : base (name, is_new, attrs)
+ public InterfaceSetGetBase (Expression type, string name, bool is_new,
+ bool has_get, bool has_set, Attributes prop_attrs, Attributes get_attrs,
+ Attributes set_attrs, Location loc)
+ :base (type, name, is_new, prop_attrs, loc)
{
- Type = type;
HasGet = has_get;
HasSet = has_set;
- Location = loc;
+ m_get = new PropertyAccessor (get_attrs);
+ m_set = new PropertyAccessor (set_attrs);
+ ReturnType = type;
}
+
+ public override EmitContext Emit (TypeContainer tc, DeclSpace ds) {
+ EmitContext ec = base.Emit (tc, ds);
+ if (ec == null)
+ ec = new EmitContext (tc, ds, Location, null, null, ModFlags, false);
+
+ m_get.Emit (ec);
+ m_set.Emit (ec);
+ return ec;
+ }
+
+ // TODO: It would be nice to have this method private
+ public void SetBuilders (PropertyBuilder pb, MethodBuilder gb, MethodBuilder sb) {
+ Builder = pb;
+ m_get.Builder = gb;
+ m_set.Builder = sb;
+ }
+
+ public override void SetCustomAttribute (CustomAttributeBuilder customBuilder) {
+ Builder.SetCustomAttribute (customBuilder);
+ }
+
}
public class InterfaceEvent : InterfaceMemberBase {
- public readonly Location Location;
- public Expression Type;
- public MyEventBuilder Builder;
+ MyEventBuilder Builder;
public InterfaceEvent (Expression type, string name, bool is_new, Attributes attrs,
Location loc)
- : base (name, is_new, attrs)
+ : base (type, name, is_new, attrs, loc)
{
- Type = type;
- Location = loc;
+ }
+
+ public override string GetSignatureForError () {
+ return TypeManager.GetFullNameSignature (Builder);
+ }
+
+ public void SetBuilder (MyEventBuilder eb) {
+ Builder = eb;
+ }
+
+ public override void SetCustomAttribute (CustomAttributeBuilder customBuilder) {
+ Builder.SetCustomAttribute (customBuilder);
}
}
public class InterfaceMethod : InterfaceMemberBase {
- public Expression ReturnType;
public readonly Parameters Parameters;
- public readonly Location Location;
- public MethodBuilder Builder;
+ MethodBuilder Builder;
public InterfaceMethod (Expression return_type, string name, bool is_new, Parameters args,
Attributes attrs, Location l)
- : base (name, is_new, attrs)
+ : base (return_type, name, is_new, attrs, l)
{
- this.ReturnType = return_type;
this.Parameters = args;
- Location = l;
+ }
+
+ public override EmitContext Emit(TypeContainer tc, DeclSpace ds) {
+ EmitContext ec = base.Emit(tc, ds);
+ if (ec == null)
+ ec = new EmitContext (tc, ds, Location, null, null, ModFlags, false);
+
+ MethodCore.LabelParameters (ec, Builder, Parameters, OptAttributes, Location);
+ return ec;
}
/// <summary>
return (IsNew ? "new-" : "") + ret.FullName + "(" + args + ")";
}
+ public override string GetSignatureForError () {
+ return TypeManager.CSharpSignature (Builder);
+ }
+
public Type [] ParameterTypes (DeclSpace ds)
{
return Parameters.GetParameterInfo (ds);
}
+
+ public void SetBuilder (MethodBuilder mb) {
+ Builder = mb;
+ }
+
+ public override void SetCustomAttribute(CustomAttributeBuilder customBuilder) {
+ Builder.SetCustomAttribute (customBuilder);
+ }
+ }
+
+ public class InterfaceProperty : InterfaceSetGetBase
+ {
+ public InterfaceProperty (Expression type, string name,
+ bool is_new, bool has_get, bool has_set,
+ Attributes prop_attrs, Attributes get_attrs,
+ Attributes set_attrs, Location loc)
+ : base (type, name, is_new, has_get, has_set, prop_attrs, get_attrs, set_attrs, loc)
+ {
+ }
+
+ public override string GetSignatureForError () {
+ return TypeManager.CSharpSignature (Builder, false);
+ }
}
- public class InterfaceIndexer : InterfaceMemberBase {
- public readonly bool HasGet, HasSet;
+ public class InterfaceIndexer : InterfaceSetGetBase {
public readonly Parameters Parameters;
- public readonly Location Location;
- public Expression Type;
- public PropertyBuilder Builder;
-
+
public InterfaceIndexer (Expression type, Parameters args, bool do_get, bool do_set,
- bool is_new, Attributes attrs, Location loc)
- : base ("", is_new, attrs)
+ bool is_new, Attributes attrs, Attributes get_attrs, Attributes set_attrs,
+ Location loc)
+ : base (type, "Item", is_new, do_get, do_set, attrs, get_attrs, set_attrs, loc)
{
- Type = type;
Parameters = args;
- HasGet = do_get;
- HasSet = do_set;
- Location = loc;
}
- public Type [] ParameterTypes (DeclSpace ds)
- {
+ public override string GetSignatureForError() {
+ return TypeManager.CSharpSignature (Builder, true);
+ }
+
+ public Type [] ParameterTypes (DeclSpace ds) {
return Parameters.GetParameterInfo (ds);
}
}
return false;
if (!CheckContext (ec, loc))
return false;
+
Type iterator_type = IteratorHandler.Current.IteratorType;
if (expr.Type != iterator_type){
Create_Current ();
Create_Dispose ();
- if (return_type == TypeManager.ienumerable_type){
+ if (IsIEnumerable (return_type)){
Create_GetEnumerator ();
RootContext.RegisterHelperClass (enumerable_proxy_class);
}
// Create the proxy class type.
handler.MakeEnumeratorProxy ();
- if (handler.return_type == TypeManager.ienumerable_type)
+ if (IsIEnumerable (handler.return_type))
handler.MakeEnumerableProxy ();
type = handler.return_type;
{
handler.LoadArgs (ec.ig);
- if (handler.return_type == TypeManager.ienumerable_type)
+ if (IsIEnumerable (handler.return_type))
ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) handler.enumerable_proxy_constructor);
else
ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) handler.enumerator_proxy_constructor);
return ret_val;
}
}
+
+ static bool IsIEnumerable (Type t)
+ {
+ return t == TypeManager.ienumerable_type || TypeManager.ImplementsInterface (t, TypeManager.ienumerable_type);
+ }
+
+ static bool IsIEnumerator (Type t)
+ {
+ return t == TypeManager.ienumerator_type || TypeManager.ImplementsInterface (t, TypeManager.ienumerator_type);
+ }
//
// Returns the new block for the method, or null on failure
//
public Block Setup (Block block)
{
- if (return_type != TypeManager.ienumerator_type &&
- return_type != TypeManager.ienumerable_type){
+ if (!(IsIEnumerator (return_type) || IsIEnumerable (return_type))){
Report.Error (
-205, loc, String.Format (
- "The method `{0}' contains a yield statement, but has an invalid return type for an iterator",
- name));
+ "The method `{0}' contains a yield statement, but has an invalid return type for an iterator `{1}'",
+ name, TypeManager.CSharpName (return_type)));
return null;
}
public readonly Modifier ModFlags;
public Attributes OptAttributes;
public readonly string Name;
- public Type parameter_type;
+ Type parameter_type;
public Parameter (Expression type, string name, Modifier mod, Attributes attrs)
{
//
public static Hashtable AllDefines = new Hashtable ();
- //
- // The list of global attributes (those that target the assembly)
- //
- static Hashtable global_attributes = new Hashtable ();
-
//
// Whether we are being linked against the standard libraries.
// This is only used to tell whether `System.Object' should
// Because of the strange way in which we do things, global
// attributes must be processed first.
//
- if (global_attributes.Count > 0){
- AssemblyBuilder ab = CodeGen.AssemblyBuilder;
- TypeContainer dummy = new TypeContainer ();
- EmitContext temp_ec = new EmitContext (
- dummy, Mono.CSharp.Location.Null, null, null, 0, false);
-
- foreach (DictionaryEntry de in global_attributes){
- NamespaceEntry ns = (NamespaceEntry) de.Key;
- Attributes attrs = (Attributes) de.Value;
-
- dummy.NamespaceEntry = ns;
- Attribute.ApplyAttributes (temp_ec, ab, ab, attrs);
- }
- }
+ CodeGen.Assembly.Emit ();
+ CodeGen.Module.Emit ();
if (attribute_types != null)
foreach (TypeContainer tc in attribute_types)
if (EmitCodeHook != null)
EmitCodeHook ();
-
-
- if (Unsafe) {
- if (TypeManager.unverifiable_code_ctor == null) {
- Console.WriteLine ("Internal error ! Cannot set unverifiable code attribute.");
- return;
- }
-
- CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor,
- new object [0]);
- CodeGen.ModuleBuilder.SetCustomAttribute (cb);
- }
}
//
FieldBuilder fb;
if (impl_details_class == null){
- impl_details_class = CodeGen.ModuleBuilder.DefineType (
+ impl_details_class = CodeGen.Module.Builder.DefineType (
"<PrivateImplementationDetails>",
TypeAttributes.NotPublic,
TypeManager.object_type);
return fb;
}
-
- //
- // Adds a global attribute that was declared in `container',
- // the attribute is in `attr', and it was defined at `loc'
- //
- static public void AddGlobalAttributeSection (TypeContainer container, AttributeSection attr)
- {
- NamespaceEntry ns = container.NamespaceEntry;
- Attributes a = (Attributes) global_attributes [ns];
-
- if (a == null)
- global_attributes [ns] = new Attributes (attr);
- else
- a.AddAttributeSection (attr);
- }
}
}
if (hm == null){
error1579 (expr.Type);
return false;
- }
+ }
array_type = expr.Type;
element_type = hm.element_type;
// Ok, we can access it, now make sure that we can do something
// with this `GetEnumerator'
//
-
+
+ Type return_type = mi.ReturnType;
if (mi.ReturnType == TypeManager.ienumerator_type ||
- TypeManager.ienumerator_type.IsAssignableFrom (mi.ReturnType) ||
- (!RootContext.StdLib && TypeManager.ImplementsInterface (mi.ReturnType, TypeManager.ienumerator_type))) {
- if (declaring != TypeManager.string_type) {
+ TypeManager.ienumerator_type.IsAssignableFrom (return_type) ||
+ (!RootContext.StdLib && TypeManager.ImplementsInterface (return_type, TypeManager.ienumerator_type))) {
+
+ //
+ // If it is not an interface, lets try to find the methods ourselves.
+ // For example, if we have:
+ // public class Foo : IEnumerator { public bool MoveNext () {} public int Current { get {}}}
+ // We can avoid the iface call. This is a runtime perf boost.
+ // even bigger if we have a ValueType, because we avoid the cost
+ // of boxing.
+ //
+ // We have to make sure that both methods exist for us to take
+ // this path. If one of the methods does not exist, we will just
+ // use the interface. Sadly, this complex if statement is the only
+ // way I could do this without a goto
+ //
+
+ if (return_type.IsInterface ||
+ (hm.move_next = FetchMethodMoveNext (return_type)) == null ||
+ (hm.get_current = FetchMethodGetCurrent (return_type)) == null) {
+
hm.move_next = TypeManager.bool_movenext_void;
hm.get_current = TypeManager.object_getcurrent_void;
- return true;
+ return true;
}
- }
- //
- // Ok, so they dont return an IEnumerable, we will have to
- // find if they support the GetEnumerator pattern.
- //
- Type return_type = mi.ReturnType;
-
- hm.move_next = FetchMethodMoveNext (return_type);
- if (hm.move_next == null)
- return false;
- hm.get_current = FetchMethodGetCurrent (return_type);
- if (hm.get_current == null)
- return false;
+ } else {
+ //
+ // Ok, so they dont return an IEnumerable, we will have to
+ // find if they support the GetEnumerator pattern.
+ //
+
+ hm.move_next = FetchMethodMoveNext (return_type);
+ if (hm.move_next == null)
+ return false;
+
+ hm.get_current = FetchMethodGetCurrent (return_type);
+ if (hm.get_current == null)
+ return false;
+ }
+
hm.element_type = hm.get_current.ReturnType;
hm.enumerator_type = return_type;
hm.is_disposable = !hm.enumerator_type.IsSealed ||
Label end_try = ig.DefineLabel ();
ig.MarkLabel (ec.LoopBegin);
- enumerator.EmitLoad ();
- ig.Emit (OpCodes.Callvirt, hm.move_next);
+
+ enumerator.EmitCall (hm.move_next);
+
ig.Emit (OpCodes.Brfalse, end_try);
if (ec.InIterator)
ec.EmitThis ();
- enumerator.EmitLoad ();
- ig.Emit (OpCodes.Callvirt, hm.get_current);
+ enumerator.EmitCall (hm.get_current);
if (ec.InIterator){
conv.Emit (ec);
for (int i = 0; i < rank; i++)
args [i] = TypeManager.int32_type;
- ModuleBuilder mb = CodeGen.ModuleBuilder;
+ ModuleBuilder mb = CodeGen.Module.Builder;
get = mb.GetArrayMethod (
array_type, "Get",
CallingConventions.HasThis| CallingConventions.Standard,
//
if (ret == null){
if (pointers [t] == null)
- pointers [t] = CodeGen.ModuleBuilder.GetType (tname);
+ pointers [t] = CodeGen.Module.Builder.GetType (tname);
ret = (Type) pointers [t];
}
args [2] = enum_type;
args [3] = void_type;
- set_corlib_type_builders.Invoke (CodeGen.AssemblyBuilder, args);
+ set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
} else {
// Compatibility for an older version of the class libs.
set_corlib_type_builders = GetMethod (
args [1] = value_type;
args [2] = enum_type;
- set_corlib_type_builders.Invoke (CodeGen.AssemblyBuilder, args);
+ set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
}
}