// Semantic checking public override void ResolveMember( TypeEntry symDefiningClass, ISemanticResolver s, ICLRtypeProvider provider ) { //TypeEntry tRetType = null; if (!IsCtor) { m_tRetType.ResolveType(s); //tRetType = m_tRetType.TypeRec; } else { ClassDecl nodeClass = symDefiningClass.Node; if (Mods.IsStatic) { // Checks on static ctors if (this.Params.Length != 0) { //s.ThrowError_NoParamsOnStaticCtor(this); ThrowError(SymbolError.NoParamsOnStaticCtor(this)); } // Rename to avoid a naming collision w/ a default ctor. // Since no one will call a static ctor (and codegen ignores ctor names), // we can pick anything here. //this.m_strName = "$static_ctor"; this.m_idName = new Identifier("$static_ctor", m_idName.Location); // Is there a static field initializer to chain to? if (nodeClass.StaticInitMethod != null) { /* Statement stmt = new ExpStatement( new MethodCallExp( null, new Identifier(nodeClass.StaticInitMethod.Name, nodeClass.StaticInitMethod.Location), new ArgExp[0] )); */ // If there are Static, ReadOnly fields, then they must be assigned directly // in a constructor, not in a function called by the constructor. Statement stmt = nodeClass.StaticInitMethod.Body; Body.InjectStatementAtHead(stmt); } } // static ctor else { if (nodeClass.InstanceInitMethod != null) { // Chain to an instance-field initializer if we don't chain to // a this() ctor. CtorChainStatement chain = (this.Body.Statements[0]) as CtorChainStatement; Debug.Assert(chain != null); if (chain.TargetType == CtorChainStatement.ETarget.cBase) { /* Statement stmt = new MethodCallStatement( new MethodCallExp( null, new Identifier(nodeClass.InstanceInitMethod.Name, nodeClass.InstanceInitMethod.Location), new ArgExp[0] )); */ // PEVerify barfs if we try to do an instance method call in the ctor, // so just inject the raw method body. It's just a bunch of assigns anyway, // so we're ok. Statement stmt = nodeClass.InstanceInitMethod.Body; Body.InjectStatementAtHead(stmt); } } } // instance ctor } // Add new sym entry to our parent class's scope MethodExpEntry m = new MethodExpEntry( Name, this, symDefiningClass, IsCtor ? null : m_tRetType.BlueType ); m.m_scope = new Scope( "method: " + symDefiningClass.m_strName + "." + Name, this, symDefiningClass.MemberScope); m_symbol = m; //s.PushScope(m.m_scope); Scope prev = s.SetCurrentContext(m.m_scope); // resolve params (because we'll need them for overloading) // Add param 0 for 'this' (if not static) // For structs, "this" is a reference, for classes, it's a value. if (!Mods.IsStatic) { ParamVarExpEntry e = new ParamVarExpEntry(); e.m_strName = "this"; TypeEntry t = m_symbol.SymbolClass; if (t.IsStruct) { t = new RefTypeEntry(t, s); } e.m_type = t; // 'this' is the type of the containg class e.CodeGenSlot = 0; s.GetCurrentContext().AddSymbol(e); } // do rest of the params foreach(ParamVarDecl param in m_arParams) { param.ResolveVarDecl(s); } //s.PopScope(m.m_scope); s.RestoreContext(prev); symDefiningClass.AddMethodToScope(m); }
// Semantic Checking // - Create a symbol entry for this local // - Resolve the ObjExp to a type internal void ResolveVarDecl(ISemanticResolver s) { // Convert our Object Expression into a TypeEntry // Note that at this point, all defined & imported types should be added // So if this is null, it's undefined. m_tType.ResolveType(s); TypeEntry t = m_tType.BlueType; Debug.Assert(t != null); // Create a symbol entry VarExpEntry sym = Symbol; sym.m_strName = m_stName; sym.m_type = t; s.GetCurrentContext().AddSymbol(sym); }
public void ResolveMemberAsLiteral(TypeEntry symDefiningClass, ISemanticResolver s, object o) { //f.FieldTypeSig.ResolveType(s); m_tType.ResolveType(s); TypeEntry t = m_tType.BlueType; m_symbol = new LiteralFieldExpEntry(Name, t, symDefiningClass, this); LiteralFieldExpEntry l = (LiteralFieldExpEntry) m_symbol; l.Data = o; s.GetCurrentContext().AddSymbol(m_symbol); }
// Resolve this public override void ResolveMember( TypeEntry symDefiningClass, ISemanticResolver s, ICLRtypeProvider provider ) { m_tType.ResolveType(s); // Spoof bodies if (HasGet) { m_declGet.ResolveMember(symDefiningClass, s, null); m_declGet.Symbol.IsSpecialName = true; } if (HasSet) { m_declSet.ResolveMember(symDefiningClass, s, null); m_declSet.Symbol.IsSpecialName = true; } // Create a symbol for the property m_symbol = new SymbolEngine.PropertyExpEntry(symDefiningClass, this, m_declGet, m_declSet); s.GetCurrentContext().AddSymbol(m_symbol); }
// Resolve member public override void ResolveMember( TypeEntry symDefiningClass, ISemanticResolver s, ICLRtypeProvider provider ) { m_tType.ResolveType(s); TypeEntry t = m_tType.BlueType; m_symbol = new FieldExpEntry(m_stName, t, symDefiningClass, this); s.GetCurrentContext().AddSymbol(m_symbol); m_symbol.SetInfo(provider); }
// Resolve the events public override void ResolveMember( TypeEntry symDefiningClass, ISemanticResolver s, ICLRtypeProvider provider ) { m_tType.ResolveType(s); m_symbol = new EventExpEntry(symDefiningClass, this); s.GetCurrentContext().AddSymbol(m_symbol); // If an event has no handlers if (m_addMethod == null && m_addMethod == null) { FixDefaultHandlers(symDefiningClass, s, provider); } Debug.Assert(m_addMethod != null && m_removeMethod != null); Debug.Assert(m_addMethod.Symbol == null); // shouldn't have resolved handlers yet Debug.Assert(m_removeMethod.Symbol == null); // The handlers should be treated just like normal methods.. ClassDecl c = symDefiningClass.Node; c.AddMethodToList(m_addMethod); c.AddMethodToList(m_removeMethod); }
// Now that all the types have been stubbed and established their context, // we can recursively run through and resolve all of our base types. void FixBaseTypes( ISemanticResolver s, ICLRtypeProvider provider ) { TypeEntry tSuper = null; BeginCheckCycle(s); ArrayList alInterfaces = new ArrayList(); // Decide who our super class is and which interfaces we're inheriting foreach(TypeSig sig in this.m_arSuper) { sig.ResolveType(s); TypeEntry t = sig.BlueType; // Make sure this base type is resolved. Do this recursively ClassDecl c = t.Node; if (c != null) { c.ResolveTypesAsCLR(s, provider); } if (t.IsClass) { Debug.Assert(this.IsClass, "Only a class can have a super-class"); if (tSuper != null) { ThrowError(SymbolError.OnlySingleInheritence(this)); } tSuper = t; } else { // Both structs & interfaces can only derive from interfaces (not classes) if (!t.IsInterface) ThrowError(SymbolError.MustDeriveFromInterface(this, t)); alInterfaces.Add(t); } } TypeEntry [] tInterfaces = new TypeEntry[alInterfaces.Count]; for(int i = 0; i < alInterfaces.Count; i++) tInterfaces[i] = (TypeEntry) alInterfaces[i]; // If no super class is specified, then we use as follows: // 'Interface' has no super class, // 'Class' has 'System.Object' // 'Struct' has 'System.ValueType' if (!IsInterface && (tSuper == null)) { if (IsClass) tSuper = s.ResolveCLRTypeToBlueType(typeof(object)); if (IsStruct) tSuper = s.ResolveCLRTypeToBlueType(typeof(System.ValueType)); } Debug.Assert(IsInterface ^ (tSuper != null)); // Just to sanity check, make sure the symbol stub is still there #if DEBUG TypeEntry sym = (TypeEntry) s.GetCurrentContext().LookupSymbolInThisScopeOnly(m_strName); Debug.Assert(sym == m_symbol); #endif m_symbol.InitLinks(tSuper, tInterfaces); // Make sure all of our base types are resolved foreach(TypeEntry t in this.Symbol.BaseInterfaces) { t.EnsureResolved(s); } if (Symbol.Super != null) Symbol.Super.EnsureResolved(s); // Final call. Set super scope m_symbol.FinishInit(); EndCheckCycle(); }
// Semantic resolution public override void ResolveStatement(ISemanticResolver s) { Scope prev = null; if (this.m_arLocals.Length != 0) { //s.PushScope(m_scopeLocals); m_scopeLocals = new Scope("block_scope", null, s.GetCurrentContext()); prev = s.SetCurrentContext(m_scopeLocals); } foreach(LocalVarDecl v in Locals) { v.ResolveVarDecl(s); } foreach(Statement stmt in Statements) { stmt.ResolveStatement(s); } if (m_scopeLocals != null) //s.PopScope(m_scopeLocals); s.RestoreContext(prev); }
// Semantic resolution public override void ResolveStatement(ISemanticResolver s) { // Label must have not been defined. m_symbol = (LabelEntry) s.LookupSymbol(s.GetCurrentContext(), m_label, false); if (m_symbol != null) { // Error, label already defined. ThrowError(SymbolError.LabelAlreadyDefined(m_label.Text, m_label.Location, m_symbol.Node.LabelId.Location)); /* s.ThrowError(SymbolEngine.SemanticChecker.Code.cLabelAlreadyDefined, m_label.Location, "Label '" + m_label.Text + "' is already defined at '"+ m_symbol.Node.LabelId.Location + "' in the current scope"); */ } m_symbol = new LabelEntry(m_label.Text, this); s.GetCurrentContext().AddSymbol(m_symbol); }