//----------------------------------------------------------------------------- // Parse an interface // // ** rules ** // InterfaceDecl-> 'interface' id:name '{' body '}' // InterfaceDecl-> 'interface' id:name ':' base_list '{' body '}' //----------------------------------------------------------------------------- protected ClassDecl ParseInterface(Modifiers modsInterface) { Token t; ReadExpectedToken(Token.Type.cInterface); Identifier idName = ReadExpectedIdentifier(); TypeSig[] arBase = null; //if (!modsInterface.IsPublic) //modsInterface.FlagSetter |= Modifiers.EFlags.Private; if (modsInterface.VisibilityNotSet) modsInterface.SetPrivate(); ArrayList alMethods = new ArrayList(); ArrayList alProperties = new ArrayList(); // Read list of base interfaces that we derive from t = m_lexer.PeekNextToken(); if (t.TokenType == Token.Type.cColon) { ConsumeNextToken(); // ':' arBase = ParseIdNameList(); } ReadExpectedToken(Token.Type.cLCurly); // Read members t = m_lexer.PeekNextToken(); while(t.TokenType != Token.Type.cRCurly) { // member: // method -> rettype id:name '(' param_list ')' ';' // property -> rettype id:name '{' set ';' get ';' '}' TypeSig rettype = ParseTypeSig(); Identifier idMember = ReadExpectedIdentifier(); t = m_lexer.PeekNextToken(); // All interface members have these attributes /* AST.Modifiers mods = new AST.Modifiers( AST.Modifiers.EFlags.Abstract | AST.Modifiers.EFlags.Virtual | AST.Modifiers.EFlags.Public ); */ Modifiers mods = new Modifiers(); mods.SetAbstract(); mods.SetVirtual(); mods.SetPublic(); // Method if (t.TokenType == Token.Type.cLParen) { MemberDecl m = this.PartialParseMethodDecl(mods, rettype, idMember, Genre.cInterface); alMethods.Add(m); } // Property else if (t.TokenType == Token.Type.cLCurly) { PropertyDecl p = PartialParsePropertyDecl(mods, rettype, idMember); alProperties.Add(p); } // Indexer else if (t.TokenType == Token.Type.cLSquare) { PropertyDecl p = PartialParseIndexerDecl(mods, rettype, idMember); alProperties.Add(p); } // Error else { //this.ThrowError_UnexpectedToken(t); ThrowError(E_UnexpectedToken(t)); } t = m_lexer.PeekNextToken(); } ReadExpectedToken(Token.Type.cRCurly); // '}' MethodDecl [] arMethods = this.MethodDeclFromArray(alMethods); PropertyDecl [] arProperties = this.PropertyDeclFromArray(alProperties); ClassDecl d = new ClassDecl(idName, arBase, arMethods, arProperties, modsInterface); return d; }
// Resolve all the fields in this type. Only class/struct should call // this. void FixFields(ISemanticResolver s, ICLRtypeProvider provider) { Debug.Assert(!IsInterface); int cInstance = 0; int cStatic = 0; foreach(FieldDecl f in m_alFields) { f.ResolveMember(m_symbol, s, provider); //f.Symbol.SetInfo(provider); if (f.InitialExp != null) if (f.Mods.IsStatic) cStatic++; else cInstance++; } Statement [] stmtStatic = new Statement[cStatic]; Statement [] stmtInstance = new Statement[cInstance]; cStatic = 0; cInstance = 0; // Fields can have assignments. Make 2 helper functions to do // assignment for static & instance fields foreach(FieldDecl f in m_alFields) { if (f.InitialExp != null) { Statement stmt = new ExpStatement(new AssignStmtExp( new SimpleObjExp(new Identifier(f.Name, f.Location)), f.InitialExp)); if (f.Mods.IsStatic) { stmtStatic[cStatic] = stmt; cStatic++; } else { if (IsStruct) { //ThrowError_NoFieldInitForStructs(s, f); ThrowError(SymbolError.NoFieldInitForStructs(f)); } stmtInstance[cInstance] = stmt; cInstance ++; } } // end has initializer expression } Debug.Assert(cStatic == stmtStatic.Length); Debug.Assert(cInstance == stmtInstance.Length); // Create methods to initialize the static & instance fields. // Then the ctors can call these methods if (cStatic != 0) { Modifiers mods = new Modifiers(); mods.SetStatic(); mods.SetPrivate(); m_nodeStaticInit = new MethodDecl( new Identifier(".StaticInit", this.Location), new ResolvedTypeSig(typeof(void), s), new ParamVarDecl[0], new BlockStatement(null, stmtStatic), mods ); //AddMethodToList(m_nodeStaticInit); } if (cInstance != 0) { Modifiers mods = new Modifiers(); mods.SetPrivate(); m_nodeInstanceInit = new MethodDecl( new Identifier(".InstanceInit", this.Location), new ResolvedTypeSig(typeof(void), s), new ParamVarDecl[0], new BlockStatement(null, stmtInstance), mods ); AddMethodToList(m_nodeInstanceInit); } } // end fields
//----------------------------------------------------------------------------- // Parse Member attributes and return the bit flag // // ** rules ** // MemberAttr -> <any subset of {public, static, etc } > //----------------------------------------------------------------------------- protected Modifiers ParseModifiers() { AST.Modifiers mods = new Modifiers(); while(true) { Token t = m_lexer.PeekNextToken(); switch(t.TokenType) { case Token.Type.cAttrPublic: mods.SetPublic(); break; case Token.Type.cAttrProtected: mods.SetProtected(); break; case Token.Type.cAttrPrivate: mods.SetPrivate(); break; case Token.Type.cAttrStatic: mods.SetStatic(); break; case Token.Type.cAttrAbstract: mods.SetAbstract(); break; case Token.Type.cAttrVirtual: mods.SetVirtual(); break; case Token.Type.cAttrOverride: mods.SetOverride(); break; case Token.Type.cAttrInternal: mods.SetInternal(); break; case Token.Type.cAttrReadOnly: mods.SetReadOnly(); break; case Token.Type.cNew: mods.SetNew(); break; case Token.Type.cAttrSealed: mods.SetSealed(); break; // Return once we encounter something that's not a modifier default: { return mods; } } ConsumeNextToken(); } // We exit once we find a token that's not a modifier (or we find a duplicate modifier) }