public override bool VisitParameterIdentifier(ParameterIdentifier parameterIdentifier) { ISymbolTable namescope = parameterIdentifier.Parent.SymbolTable; System.Diagnostics.Debug.Assert(namescope != null); System.Diagnostics.Debug.Assert(namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Block); if (!identifierService.IsValidFormatParameterName(parameterIdentifier.Name)) { errorReport.Error("TODOFILENAME", parameterIdentifier.Position, "'{0}' is an invalid parameter name.", parameterIdentifier.Name); return(false); } System.Diagnostics.Debug.Assert(!namescope.IsDefined(parameterIdentifier.Name)); namescope.AddVariable(parameterIdentifier); return(base.VisitParameterIdentifier(parameterIdentifier)); }
private bool ApplyDeclarationRules(Identifier ident, ISymbolTable namescope, SingleVariableDeclarationStatement typeDecl, IStatement statem) { // Second simple case: a local var and we are on the right place to // declare it if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { namescope.AddVariable(ident); return true; } // More complex: a block or compound tries to redefine a variable if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { if (namescope.Parent.IsDefined(ident.Name)) { errorReport.Error( "TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined in a parent scope.", ident.Name ); return false; } } // Local variables at class level? // We will support that as a type initializer, but not now. if (ident.Type == IdentifierType.Local && namescope.ScopeType == ScopeType.Type) { errorReport.Error( "TODOFILENAME", typeDecl.Position, "At type level, just instance or static fields are allowed (yet)" ); return false; } // Static or instance in a method/block/compound are moved // to the parent class or source unit level if (ident.Type == IdentifierType.InstanceField || ident.Type == IdentifierType.StaticField) { if (namescope.ScopeType == ScopeType.SourceUnit || namescope.ScopeType == ScopeType.Type) { namescope.AddVariable(ident); } else if (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block) { IASTNode node = statem.Parent; while(node != null && node.NodeType != NodeType.TypeDefinition && node.NodeType != NodeType.SourceUnit) { node = node.Parent; } if (node == null || node.SymbolTable == null) { errorReport.Error( "TODOFILENAME", typeDecl.Position, "Compiler error: The instance of static declaration '{0}' could not be mapped to a parent type", ident.Name ); return false; } ISymbolTable parentScope = node.SymbolTable; IStatementContainer typeStmtsContainer = node as IStatementContainer; System.Diagnostics.Debug.Assert( parentScope != null ); System.Diagnostics.Debug.Assert( typeStmtsContainer != null ); if (parentScope.IsDefined(ident.Name)) { errorReport.Error( "TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined.", ident.Name ); return false; } else { parentScope.AddVariable(ident); // We can replace the declaration on the method // body with an assignment if and only if this type decl has // an init expression, so CreateAssignmentFromTypeDecl can return null AssignmentExpression assignExp = CreateAssignmentFromTypeDecl(typeDecl); ExpressionStatement assignExpStmt = new ExpressionStatement(assignExp); typeDecl.ConvertInitExpressionToDependency(); // Replace the declaration with an assignment (statem.Parent as IStatementContainer).Statements.Replace(typeDecl, assignExpStmt); // Add the member/field declaration to the parent typeStmtsContainer.Statements.Add( typeDecl ); // TODO: Link assignment expression and typeDecl to help // find out the type of the field later return true; } } } return false; }
private bool ApplyDeclarationRules(Identifier ident, ISymbolTable namescope, SingleVariableDeclarationStatement typeDecl, IStatement statem) { // Second simple case: a local var and we are on the right place to // declare it if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { namescope.AddVariable(ident); return(true); } // More complex: a block or compound tries to redefine a variable if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { if (namescope.Parent.IsDefined(ident.Name)) { errorReport.Error("TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined in a parent scope.", ident.Name); return(false); } } // Local variables at class level? // We will support that as a type initializer, but not now. if (ident.Type == IdentifierType.Local && namescope.ScopeType == ScopeType.Type) { errorReport.Error("TODOFILENAME", typeDecl.Position, "At type level, just instance or static fields are allowed (yet)"); return(false); } // Static or instance in a method/block/compound are moved // to the parent class or source unit level if (ident.Type == IdentifierType.InstanceField || ident.Type == IdentifierType.StaticField) { if (namescope.ScopeType == ScopeType.SourceUnit || namescope.ScopeType == ScopeType.Type) { namescope.AddVariable(ident); } else if (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block) { IASTNode node = statem.Parent; while (node != null && node.NodeType != NodeType.TypeDefinition && node.NodeType != NodeType.SourceUnit) { node = node.Parent; } if (node == null || node.SymbolTable == null) { errorReport.Error("TODOFILENAME", typeDecl.Position, "Compiler error: The instance of static declaration '{0}' could not be mapped to a parent type", ident.Name); return(false); } ISymbolTable parentScope = node.SymbolTable; IStatementContainer typeStmtsContainer = node as IStatementContainer; System.Diagnostics.Debug.Assert(parentScope != null); System.Diagnostics.Debug.Assert(typeStmtsContainer != null); if (parentScope.IsDefined(ident.Name)) { errorReport.Error("TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined.", ident.Name); return(false); } else { parentScope.AddVariable(ident); // We can replace the declaration on the method // body with an assignment if and only if this type decl has // an init expression, so CreateAssignmentFromTypeDecl can return null AssignmentExpression assignExp = CreateAssignmentFromTypeDecl(typeDecl); ExpressionStatement assignExpStmt = new ExpressionStatement(assignExp); typeDecl.ConvertInitExpressionToDependency(); // Replace the declaration with an assignment (statem.Parent as IStatementContainer).Statements.Replace(typeDecl, assignExpStmt); // Add the member/field declaration to the parent typeStmtsContainer.Statements.Add(typeDecl); // TODO: Link assignment expression and typeDecl to help // find out the type of the field later return(true); } } } return(false); }