// For non-interface types public ClassDecl( Identifier idName, TypeSig [] arSuper, // super class & implemented interfaces MethodDecl [] alMethods, PropertyDecl[] alProperties, FieldDecl[] alFields, EventDecl [] alEvents, TypeDeclBase[] alNestedTypes, Modifiers mods, bool fIsClass // true for class, false for struct ) { Debug.Assert(idName != null); Debug.Assert(alMethods != null); Debug.Assert(alFields != null); Debug.Assert(alProperties != null); Debug.Assert(alEvents != null); m_strName = idName.Text; m_arSuper = (arSuper == null) ? new TypeSig[0] : arSuper; m_alNestedTypes = (alNestedTypes == null) ? m_sEmptyTypeList : alNestedTypes; m_alMethods = alMethods; m_alProperties = alProperties; m_alFields = alFields; m_alEvents = alEvents; // @todo - this is wrong m_filerange = idName.Location; if (!fIsClass) // structs are implicitly sealed. mods.SetSealed(); m_mods = mods; m_genre = fIsClass ? TypeEntry.Genre.cClass : TypeEntry.Genre.cStruct; }
// Any of the array parameters may be null public NamespaceDecl( Identifier idName, // must be non-null UsingDirective [] arUsingDirectives, NamespaceDecl[] arNestedNamespaces, ClassDecl[] arClasses, TypeDeclBase[] arTypes ) { m_idName = idName; m_arUsingDirectives = (arUsingDirectives == null) ? new UsingDirective [0] : arUsingDirectives; m_arNestedNamespaces = (arNestedNamespaces == null) ? new NamespaceDecl[0] : arNestedNamespaces; //m_arClasses = (arClasses == null) ? new ClassDecl[0] : arClasses; Debug.Assert(arClasses == null); m_arTypes = (arTypes == null) ? new TypeDeclBase[0] : arTypes; }
protected ClassDecl ParseClassOrStruct(Modifiers modsClass, bool fIsClass) { Token t; if (fIsClass) ReadExpectedToken(Token.Type.cClass); else ReadExpectedToken(Token.Type.cStruct); // Get Name of the type Identifier stClassName = ReadExpectedIdentifier(); t = m_lexer.PeekNextToken(); // Get base list TypeSig[] arBase = null; if (t.TokenType == Token.Type.cColon) { ConsumeNextToken(); arBase = ParseIdNameList(); } ReadExpectedToken(Token.Type.cLCurly); ArrayList alMethods = new ArrayList(); ArrayList alFields = new ArrayList(); ArrayList alProperties = new ArrayList(); ArrayList alNestedTypes = new ArrayList(); ArrayList alEvents = new ArrayList(); // Parse list of memberdecls // We peek at the first token. If it's a '}', then we're done parsing members, // Else Figure out what type of member this is and parse it. t = m_lexer.PeekNextToken(); while (t.TokenType != Token.Type.cRCurly) { // mods -> <set of member modifiers, like public, protected, static, etc> // type -> <some type> // ctordecl -> attrs id '(' paramlist ')' '{' statementlist '}' // methoddecl -> attrs type id '(' paramlist ')' '{' statementlist '}' // -> attrs type 'operator' op '(' paramlist ')' body // fielddecl -> attrs type id ';' // propdecl -> attrs type id '{' ... '}' // typedecl -> attrs 'enum' ... // eventdecl -> attrs 'delegate' type id ';' // All members start with 'attrs type id'. (except ctor) So do those. Modifiers mods = ParseModifiers(); // Make private a default if (mods.VisibilityNotSet) mods.SetPrivate(); // @todo - we need a clean way to decide if this is a ctor or a methoddecl Identifier tTempId = null; t = m_lexer.PeekNextToken(); // Check events if (t.TokenType == Token.Type.cEvent) { EventDecl e = PartialParseEventDecl(mods); alEvents.Add(e); continue; } // Check if this is a nested type if (t.TokenType == Token.Type.cEnum) { EnumDecl e = ParseEnum(mods); alNestedTypes.Add(e); t = m_lexer.PeekNextToken(); continue; } if (t.TokenType == Token.Type.cDelegate) { DelegateDecl d = ParseDelegate(mods); alNestedTypes.Add(d); t = m_lexer.PeekNextToken(); continue; } if (t.TokenType == Token.Type.cClass) { ClassDecl d = ParseClass(mods); alNestedTypes.Add(d); t = m_lexer.PeekNextToken(); continue; } if (t.TokenType == Token.Type.cStruct) { ClassDecl d = ParseStruct(mods); alNestedTypes.Add(d); t = m_lexer.PeekNextToken(); continue; } // Not a nested type, so it's some other member (maybe a ctor)... if (t.TokenType == Token.Type.cId) { tTempId = t.Id; } TypeSig type = ParseTypeSig(); Identifier stMemberName; // Ctor - has a '(' instead of another identifier for the member name t = m_lexer.PeekNextToken(); if (t.TokenType == Token.Type.cLParen) { type = null; // ctor has a no return type stMemberName = tTempId; // If the ctor name doesn't match the class name, we have some error if (stMemberName.Text != stClassName.Text) { ThrowError(new ParserErrorException( Code.cMissingRetType, stMemberName.Location, "Missing a return type on a method" )); } } else { // Check for overloaded operator if (t.TokenType == Token.Type.cOperator) { MethodDecl m = this.PartialParseOverloadedOp(mods, type); alMethods.Add(m); t = m_lexer.PeekNextToken(); continue; } // Not a ctor, so we can go ahead and read the identifier stMemberName = ReadExpectedIdentifier(); } t = m_lexer.PeekNextToken(); // MethodDecl. Has a '(' next if (t.TokenType == Token.Type.cLParen) { MethodDecl m = PartialParseMethodDecl(mods, type, stMemberName, fIsClass ? Genre.cClass : Genre.cStruct); alMethods.Add(m); } // FieldDecl. Has a ';' (or possibly an '=') next else if ((t.TokenType == Token.Type.cSemi) || (t.TokenType == Token.Type.cAssign)) { Exp expInit = null; if (t.TokenType == Token.Type.cAssign) { ConsumeNextToken(); expInit = ParseExp(); } ReadExpectedToken(Token.Type.cSemi); FieldDecl f = new FieldDecl(stMemberName, type, mods, expInit); alFields.Add(f); } // Property else if (t.TokenType == Token.Type.cLCurly) { PropertyDecl p = PartialParsePropertyDecl(mods, type, stMemberName); alProperties.Add(p); } // Indexer else if (t.TokenType == Token.Type.cLSquare) { PropertyDecl p = PartialParseIndexerDecl(mods, type, stMemberName); alProperties.Add(p); } // Syntax error else { ThrowError(E_UnexpectedToken(t)); } t = m_lexer.PeekNextToken(); } // end member decl list ReadExpectedToken(Token.Type.cRCurly); MethodDecl [] arMethods = MethodDeclFromArray(alMethods); FieldDecl [] arFields = FieldDeclFromArray(alFields); PropertyDecl [] arProperties = PropertyDeclFromArray(alProperties); EventDecl [] arEvents = (EventDecl[]) alEvents.ToArray(typeof(EventDecl)); TypeDeclBase[] arNestedTypes = new TypeDeclBase[alNestedTypes.Count]; for(int i = 0; i < alNestedTypes.Count; i++) arNestedTypes[i] = (TypeDeclBase) alNestedTypes[i]; return new ClassDecl( stClassName, arBase, arMethods, arProperties, arFields, arEvents, arNestedTypes, modsClass, fIsClass ); }