// value will be returned if the expression is not a type
// reference
//
- public Expression ResolveAsTypeTerminal (EmitContext ec)
+ public TypeExpr ResolveAsTypeTerminal (EmitContext ec)
{
- Expression e = ResolveAsTypeStep (ec);
-
- if (e == null)
- return null;
- if (e is SimpleName)
- return null;
- return e;
+ return ResolveAsTypeStep (ec) as TypeExpr;
}
/// <summary>
break;
case ExprClass.MethodGroup:
+ if (!RootContext.V2){
if ((flags & ResolveFlags.MethodGroup) == 0) {
((MethodGroupExpr) e).ReportUsageError ();
return null;
}
+ }
break;
case ExprClass.Value:
/// </remarks>
public abstract void Emit (EmitContext ec);
+ public virtual void EmitBranchable (EmitContext ec, Label target, bool onTrue)
+ {
+ Emit (ec);
+ ec.ig.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+ }
+
/// <summary>
/// Protected constructor. Only derivate types should
/// be able to be created
else if (mi is PropertyInfo)
return new PropertyExpr (ec, (PropertyInfo) mi, loc);
else if (mi is Type){
- return new TypeExpr ((System.Type) mi, loc);
+ return new TypeExpression ((System.Type) mi, loc);
}
return null;
Report.Error (
122, loc, "`" + TypeManager.CSharpName (qualifier_type) + "." +
name + "' is inaccessible due to its protection level");
- else
+ else if (name == ".ctor") {
+ Report.Error (143, loc, String.Format ("The type {0} has no constructors defined",
+ TypeManager.CSharpName (queried_type)));
+ } else {
Report.Error (
122, loc, "`" + name + "' is inaccessible due to its " +
"protection level");
}
+ }
static public MemberInfo GetFieldFromEvent (EventExpr event_expr)
{
"a `" + sb.ToString () + "' was expected");
}
- static void Error_ConstantValueCannotBeConverted (Location l, string val, Type t)
+ static public void Error_ConstantValueCannotBeConverted (Location l, string val, Type t)
{
Report.Error (31, l, "Constant value `" + val + "' cannot be converted to " +
TypeManager.CSharpName (t));
public class EmptyCast : Expression {
protected Expression child;
+ public Expression Child {
+ get {
+ return child;
+ }
+ }
+
public EmptyCast (Expression child, Type return_type)
{
eclass = child.eclass;
public override Expression ResolveAsTypeStep (EmitContext ec)
{
DeclSpace ds = ec.DeclSpace;
- NamespaceEntry ns = ds.Namespace;
+ NamespaceEntry ns = ds.NamespaceEntry;
Type t;
string alias_value;
alias_value = null;
if (ec.ResolvingTypeTree){
- if (alias_value != null){
- if ((t = RootContext.LookupType (ds, alias_value, true, loc)) != null)
- return new TypeExpr (t, loc);
- }
-
int errors = Report.Errors;
- Type dt = ec.DeclSpace.FindType (loc, Name);
+ Type dt = ds.FindType (loc, Name);
if (Report.Errors != errors)
return null;
if (dt != null)
- return new TypeExpr (dt, loc);
+ return new TypeExpression (dt, loc);
+
+ if (alias_value != null){
+ if ((t = RootContext.LookupType (ds, alias_value, true, loc)) != null)
+ return new TypeExpression (t, loc);
+ }
}
//
//
if (alias_value != null){
if ((t = RootContext.LookupType (ds, alias_value, true, loc)) != null)
- return new TypeExpr (t, loc);
+ return new TypeExpression (t, loc);
// we have alias value, but it isn't Type, so try if it's namespace
return new SimpleName (alias_value, loc);
}
- if (ec.IsGeneric){
- TypeParameterExpr generic_type = ds.LookupGeneric (Name, loc);
-
- if (generic_type != null)
- return generic_type;
- }
-
+ TypeParameterExpr generic_type = ds.LookupGeneric (Name, loc);
+ if (generic_type != null)
+ return generic_type.ResolveAsTypeTerminal (ec);
+
//
// Stage 2: Lookup up if we are an alias to a type
// or a namespace.
//
if ((t = RootContext.LookupType (ds, Name, true, loc)) != null)
- return new TypeExpr (t, loc);
+ return new TypeExpression (t, loc);
// No match, maybe our parent can compose us
// into something meaningful.
{
Expression e = null;
- //
- // Since we are cheating (is_base is our hint
- // that we are the beginning of the name): we
- // only do the Alias lookup for namespaces if
- // the name does not include any dots in it
- //
- NamespaceEntry ns = ec.DeclSpace.Namespace;
- if (is_base && ns != null){
- string alias_value = ns.LookupAlias (Name);
- if (alias_value != null){
- Name = alias_value;
- Type t;
-
- if ((t = TypeManager.LookupType (Name)) != null)
- return new TypeExpr (t, loc);
-
- // No match, maybe our parent can compose us
- // into something meaningful.
- return this;
- }
- }
-
-
//
// Stage 1: Performed by the parser (binding to locals or parameters).
//
if (e == null && ec.ContainerType != null)
e = MemberLookup (ec, ec.ContainerType, Name, loc);
- if (e == null)
+ if (e == null) {
+ //
+ // Since we are cheating (is_base is our hint
+ // that we are the beginning of the name): we
+ // only do the Alias lookup for namespaces if
+ // the name does not include any dots in it
+ //
+ NamespaceEntry ns = ec.DeclSpace.NamespaceEntry;
+ if (is_base && ns != null){
+ string alias_value = ns.LookupAlias (Name);
+ if (alias_value != null){
+ Name = alias_value;
+ Type t;
+
+ if ((t = TypeManager.LookupType (Name)) != null)
+ return new TypeExpression (t, loc);
+
+ // No match, maybe our parent can compose us
+ // into something meaningful.
+ return this;
+ }
+ }
+
return ResolveAsTypeStep (ec);
+ }
if (e is TypeExpr)
return e;
/// <summary>
/// Fully resolved expression that evaluates to a type
/// </summary>
- public class TypeExpr : Expression {
- public TypeExpr (Type t, Location l)
+ public abstract class TypeExpr : Expression {
+ override public Expression ResolveAsTypeStep (EmitContext ec)
{
- Type = t;
- eclass = ExprClass.Type;
- loc = l;
- }
+ TypeExpr t = DoResolveAsTypeStep (ec);
+ if (t == null)
+ return null;
- public override Expression ResolveAsTypeStep (EmitContext ec)
- {
- return this;
+ eclass = ExprClass.Type;
+ return t;
}
override public Expression DoResolve (EmitContext ec)
{
- return this;
+ return ResolveAsTypeTerminal (ec);
}
override public void Emit (EmitContext ec)
throw new Exception ("Should never be called");
}
+ public virtual bool CheckAccessLevel (DeclSpace ds)
+ {
+ return ds.CheckAccessLevel (Type);
+ }
+
+ public virtual bool AsAccessible (DeclSpace ds, int flags)
+ {
+ return ds.AsAccessible (Type, flags);
+ }
+
+ public virtual bool IsClass {
+ get { return Type.IsClass; }
+ }
+
+ public virtual bool IsValueType {
+ get { return Type.IsValueType; }
+ }
+
+ public virtual bool IsInterface {
+ get { return Type.IsInterface; }
+ }
+
+ public virtual bool IsSealed {
+ get { return Type.IsSealed; }
+ }
+
+ public virtual bool CanInheritFrom ()
+ {
+ if (Type == TypeManager.enum_type ||
+ (Type == TypeManager.value_type && RootContext.StdLib) ||
+ Type == TypeManager.delegate_type ||
+ Type == TypeManager.array_type)
+ return false;
+
+ return true;
+ }
+
+ public virtual bool IsAttribute {
+ get {
+ return Type == TypeManager.attribute_type ||
+ Type.IsSubclassOf (TypeManager.attribute_type);
+ }
+ }
+
+ public virtual TypeExpr[] GetInterfaces ()
+ {
+ return TypeManager.GetInterfaces (Type);
+ }
+
+ public abstract TypeExpr DoResolveAsTypeStep (EmitContext ec);
+
+ public virtual Type ResolveType (EmitContext ec)
+ {
+ TypeExpr t = ResolveAsTypeTerminal (ec);
+ if (t == null)
+ return null;
+
+ return t.Type;
+ }
+
+ public abstract string Name {
+ get;
+ }
+
+ public override bool Equals (object obj)
+ {
+ TypeExpr tobj = obj as TypeExpr;
+ if (tobj == null)
+ return false;
+
+ return Type == tobj.Type;
+ }
+
public override string ToString ()
{
- return Type.ToString ();
+ return Name;
+ }
+ }
+
+ public class TypeExpression : TypeExpr {
+ public TypeExpression (Type t, Location l)
+ {
+ Type = t;
+ eclass = ExprClass.Type;
+ loc = l;
+ }
+
+ public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
+ {
+ return this;
+ }
+
+ public override string Name {
+ get {
+ return Type.ToString ();
+ }
}
}
public class TypeLookupExpression : TypeExpr {
string name;
- public TypeLookupExpression (string name) : base (null, Location.Null)
+ public TypeLookupExpression (string name)
{
this.name = name;
}
- public override Expression ResolveAsTypeStep (EmitContext ec)
+ public override TypeExpr DoResolveAsTypeStep (EmitContext ec)
{
if (type == null)
type = RootContext.LookupType (ec.DeclSpace, name, false, Location.Null);
return this;
}
- public override Expression DoResolve (EmitContext ec)
- {
- return ResolveAsTypeStep (ec);
- }
-
- public override void Emit (EmitContext ec)
- {
- throw new Exception ("Should never be called");
- }
-
- public override string ToString ()
- {
- return name;
+ public override string Name {
+ get {
+ return name;
+ }
}
}
FieldBase fb = TypeManager.GetField (FieldInfo);
if (fb != null)
- fb.IsAssigned = true;
+ fb.SetAssigned ();
//
// InitOnly fields can only be assigned in constructors
//
if (ec.IsConstructor){
+ if (IsStatic && !ec.IsStatic)
+ Report_AssignToReadonly (false);
+
if (ec.ContainerType == FieldInfo.DeclaringType)
return this;
}
// Handle initonly fields specially: make a copy and then
// get the address of the copy.
//
- if (FieldInfo.IsInitOnly && !ec.IsConstructor){
+ bool need_copy;
+ if (FieldInfo.IsInitOnly){
+ need_copy = true;
+ if (ec.IsConstructor){
+ if (FieldInfo.IsStatic){
+ if (ec.IsStatic)
+ need_copy = false;
+ } else
+ need_copy = false;
+ }
+ } else
+ need_copy = false;
+
+ if (need_copy){
LocalBuilder local;
-
Emit (ec);
local = ig.DeclareLocal (type);
ig.Emit (OpCodes.Stloc, local);
return;
}
- if (FieldInfo.IsStatic)
+
+ if (FieldInfo.IsStatic){
ig.Emit (OpCodes.Ldsflda, FieldInfo);
- else {
+ } else {
//
// In the case of `This', we call the AddressOf method, which will
// only load the pointer, and not perform an Ldobj immediately after
// Assembly and FamORAssem succeed if we're in the same assembly.
if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
- if (mi.DeclaringType.Assembly != invocation_type.Assembly)
- continue;
- else
+ if (mi.DeclaringType.Assembly == invocation_type.Assembly)
return mi;
}
continue;
// Family and FamANDAssem require that we derive.
- if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem)){
+ if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
if (!TypeManager.IsSubclassOrNestedChildOf (invocation_type, mi.DeclaringType))
continue;
else {
if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)){
instance_expr.Emit (ec);
ec.ig.Emit (OpCodes.Ldlen);
+ ec.ig.Emit (OpCodes.Conv_I4);
return;
}
}