📄 ecore.cs
字号:
Report.Error ( 120, l, "`{0}': An object reference is required for the nonstatic field, method or property", name); } } public bool IdenticalNameAndTypeName (EmitContext ec, Expression resolved_to, Location loc) { return resolved_to != null && resolved_to.Type != null && resolved_to.Type.Name == Name && (ec.DeclSpace.LookupType (Name, loc, /* ignore_cs0104 = */ true) != null); } public override Expression DoResolve (EmitContext ec) { return SimpleNameResolve (ec, null, false); } public override Expression DoResolveLValue (EmitContext ec, Expression right_side) { return SimpleNameResolve (ec, right_side, false); } public Expression DoResolve (EmitContext ec, bool intermediate) { return SimpleNameResolve (ec, null, intermediate); } public override FullNamedExpression ResolveAsTypeStep (EmitContext ec, bool silent) { int errors = Report.Errors; FullNamedExpression fne = ec.DeclSpace.LookupType (Name, loc, /*ignore_cs0104=*/ false); if (fne != null) return fne; if (silent || errors != Report.Errors) return null; MemberCore mc = ec.DeclSpace.GetDefinition (Name); if (mc != null) { Error_UnexpectedKind (ec, "type", GetMemberType (mc), loc); } else { NamespaceEntry.Error_NamespaceNotFound (loc, Name); } return null; } // TODO: I am still not convinced about this. If someone else will need it // implement this as virtual property in MemberCore hierarchy string GetMemberType (MemberCore mc) { if (mc is PropertyBase) return "property"; if (mc is Indexer) return "indexer"; if (mc is FieldBase) return "field"; if (mc is MethodCore) return "method"; if (mc is EnumMember) return "enum"; return "type"; } Expression SimpleNameResolve (EmitContext ec, Expression right_side, bool intermediate) { if (in_transit) return null; in_transit = true; Expression e = DoSimpleNameResolve (ec, right_side, intermediate); if (e == null) return null; if (ec.CurrentBlock == null || ec.CurrentBlock.CheckInvariantMeaningInBlock (Name, e, Location)) return e; return null; } /// <remarks> /// 7.5.2: Simple Names. /// /// Local Variables and Parameters are handled at /// parse time, so they never occur as SimpleNames. /// /// The `intermediate' flag is used by MemberAccess only /// and it is used to inform us that it is ok for us to /// avoid the static check, because MemberAccess might end /// up resolving the Name as a Type name and the access as /// a static type access. /// /// ie: Type Type; .... { Type.GetType (""); } /// /// Type is both an instance variable and a Type; Type.GetType /// is the static method not an instance method of type. /// </remarks> Expression DoSimpleNameResolve (EmitContext ec, Expression right_side, bool intermediate) { Expression e = null; // // Stage 1: Performed by the parser (binding to locals or parameters). // Block current_block = ec.CurrentBlock; if (current_block != null){ LocalInfo vi = current_block.GetLocalInfo (Name); if (vi != null){ LocalVariableReference var = new LocalVariableReference (ec.CurrentBlock, Name, loc); if (right_side != null) { return var.ResolveLValue (ec, right_side, loc); } else { ResolveFlags rf = ResolveFlags.VariableOrValue; if (intermediate) rf |= ResolveFlags.DisableFlowAnalysis; return var.Resolve (ec, rf); } } ParameterReference pref = current_block.Toplevel.GetParameterReference (Name, loc); if (pref != null) { if (right_side != null) return pref.ResolveLValue (ec, right_side, loc); else return pref.Resolve (ec); } } // // Stage 2: Lookup members // DeclSpace lookup_ds = ec.DeclSpace; Type almost_matched_type = null; ArrayList almost_matched = null; do { if (lookup_ds.TypeBuilder == null) break; e = MemberLookup (ec, lookup_ds.TypeBuilder, Name, loc); if (e != null) break; if (almost_matched == null && almostMatchedMembers.Count > 0) { almost_matched_type = lookup_ds.TypeBuilder; almost_matched = (ArrayList) almostMatchedMembers.Clone (); } lookup_ds =lookup_ds.Parent; } while (lookup_ds != null); if (e == null && ec.ContainerType != null) e = MemberLookup (ec, ec.ContainerType, Name, loc); if (e == null) { if (almost_matched == null && almostMatchedMembers.Count > 0) { almost_matched_type = ec.ContainerType; almost_matched = (ArrayList) almostMatchedMembers.Clone (); } e = ResolveAsTypeStep (ec, true); } if (e == null) { if (almost_matched != null) almostMatchedMembers = almost_matched; if (almost_matched_type == null) almost_matched_type = ec.ContainerType; MemberLookupFailed (ec, null, almost_matched_type, ((SimpleName) this).Name, ec.DeclSpace.Name, true, loc); return null; } if (e is TypeExpr) return e; if (e is MemberExpr) { MemberExpr me = (MemberExpr) e; Expression left; if (me.IsInstance) { if (ec.IsStatic || ec.IsFieldInitializer) { // // Note that an MemberExpr can be both IsInstance and IsStatic. // An unresolved MethodGroupExpr can contain both kinds of methods // and each predicate is true if the MethodGroupExpr contains // at least one of that kind of method. // if (!me.IsStatic && (!intermediate || !IdenticalNameAndTypeName (ec, me, loc))) { Error_ObjectRefRequired (ec, loc, me.GetSignatureForError ()); return null; } // // Pass the buck to MemberAccess and Invocation. // left = EmptyExpression.Null; } else { left = ec.GetThis (loc); } } else { left = new TypeExpression (ec.ContainerType, loc); } e = me.ResolveMemberAccess (ec, left, loc, null); if (e == null) return null; me = e as MemberExpr; if (me == null) return e; if (!me.IsStatic && TypeManager.IsNestedFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) && me.InstanceExpression.Type != me.DeclaringType && !me.InstanceExpression.Type.IsSubclassOf (me.DeclaringType) && (!intermediate || !IdenticalNameAndTypeName (ec, e, loc))) { Report.Error (38, loc, "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'", TypeManager.CSharpName (me.DeclaringType), TypeManager.CSharpName (me.InstanceExpression.Type)); return null; } return (right_side != null) ? me.DoResolveLValue (ec, right_side) : me.DoResolve (ec); } return e; } public override void Emit (EmitContext ec) { // // If this is ever reached, then we failed to // find the name as a namespace // Error (103, "The name `" + Name + "' does not exist in the class `" + ec.DeclSpace.Name + "'"); } public override string ToString () { return Name; } public override string GetSignatureForError () { return Name; } } /// <summary> /// Represents a namespace or a type. The name of the class was inspired by /// section 10.8.1 (Fully Qualified Names). /// </summary> public abstract class FullNamedExpression : Expression { public override FullNamedExpression ResolveAsTypeStep (EmitContext ec, bool silent) { return this; } public abstract string FullName { get; } } /// <summary> /// Expression that evaluates to a type /// </summary> public abstract class TypeExpr : FullNamedExpression { override public FullNamedExpression ResolveAsTypeStep (EmitContext ec, bool silent) { TypeExpr t = DoResolveAsTypeStep (ec); if (t == null) return null; eclass = ExprClass.Type; return t; } override public Expression DoResolve (EmitContext ec) { return ResolveAsTypeTerminal (ec, false); } 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.multicast_delegate_type || Type == TypeManager.delegate_type || Type == TypeManager.array_type) return false; return true; } public abstract TypeExpr DoResolveAsTypeStep (EmitContext ec); public Type ResolveType (EmitContext ec) { TypeExpr t = ResolveAsTypeTerminal (ec, false); if (t == null) return null; if (ec.TestObsoleteMethodUsage) { ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (t.Type); if (obsolete_attr != null) { AttributeTester.Report_ObsoleteMessage (obsolete_attr, Name, Location); } } 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 int GetHashCode () { return Type.GetHashCode (); } public override string ToString () { return Name; } } /// <summary> /// Fully resolved Expression that already evaluated to a type /// </summary> 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 override string FullName { get { return Type.FullName; } } } /// <summary> /// Used to create types from a fully qualified name. These are just used /// by the parser to setup the core types. A TypeLookupExpression is always /// classified as a type. /// </summary> public class TypeLookupExpression : TypeExpr { string name; public TypeLookupExpression (string name) { this.name = name; } static readonly char [] dot_array = { '.' }; public override TypeExpr DoResolveAsTypeStep (EmitContext ec) { if (type != null) return this; // If name is of the form `N.I', first lookup `N', then search a member `I' in it. string rest = null; string lookup_name = name; int pos = name.IndexOf ('.'); if (pos >= 0) { rest = name.Substring (pos + 1); lookup_name = name.Substring (0, pos); } FullNamedExpression resolved = RootNamespace.Global.Lookup (ec.DeclSpace, lookup_name, Location.Null); if (resolved != null && rest != null) { // Now handle the rest of the the name. string [] elements = rest.Split (dot_array); string element; int count = elements.Length; int i = 0; while (i < count && resolved != null && resolved is Namespace) { Namespace ns = resolved as Namespace; element = elements [i++]; lookup_name += "." + element; resolved = ns.Lookup (ec.DeclSpace, element, Location.Null); } if (resolved != null && resolved is TypeExpr) { Type t = ((TypeExpr) resolved).Type; while (t != null) { if (!ec.DeclSpace.CheckAccessLevel (t)) { resolved = null; lookup_name = t.FullN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -