public Program(ClassDeclaration mainClass, List<ClassDeclaration> classDeclarations) { if (mainClass != null && !mainClass.IsMainClass) { throw new ArgumentException("Illegal main class declaration, the program has no entry point."); } MainClass = mainClass; Classes = classDeclarations; }
public static ClassDeclaration CreateMainClassDeclaration(string name, MethodDeclaration mainMethod, int row, int col) { if (!mainMethod.IsEntryPoint) { throw new ArgumentException("Illegal main method declaration, the program has no entry point."); } var mainClass = new ClassDeclaration(name, null, new List<Declaration> { mainMethod }, row, col); mainClass.IsMainClass = true; return mainClass; }
public bool Handle(ClassDeclaration node) { if (NameAlreadyDefined(node.Name)) { _errorReporter.ReportError( ErrorTypes.ConflictingDefinitions, String.Format("Conflicting definitions for {0}.", node.Name), node); return false; } _types.Add(node.Name); return true; }
public void ShouldConflictWithMainClassTest() { var mainMethod = MethodDeclaration.CreateMainMethodDeclaration(new List<IStatement>(), 0, 0); var mainClass = ClassDeclaration.CreateMainClassDeclaration("Foo", mainMethod, 0, 0); var otherClass = new ClassDeclaration("Foo", null, new List<Declaration>(), 2, 0); var program = new Program(mainClass, new List<ClassDeclaration>( new ClassDeclaration[] { otherClass })); var errorReporter = new ErrorLogger(); var builder = new SymbolTableBuilder(program, errorReporter); Assert.AreEqual(SymbolTableBuilder.ExitCode.FatalError, builder.BuildSymbolTable()); var errors = errorReporter.Errors; Assert.AreEqual(errors.Count, 1); Assert.AreEqual("Conflicting definitions for Foo.", errors[0].Content); Assert.AreEqual(errors[0].Row, 2); }
public override void Visit(ClassDeclaration node) { TypeBuilder thisType = _parent._types[node.Name]; if (node.InheritedClassName != null) { // Define non-default constructor. Constructor body is not emitted // until instruction generation. TypeBuilder superClass = _parent._types[node.InheritedClassName]; thisType.SetParent(superClass); _parent._constructors[thisType] = thisType.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes); } else { _parent._constructors[thisType] = thisType.DefineDefaultConstructor(MethodAttributes.Public); } _currentType = thisType; }
public void ValidTypeDefinitionsTest() { var mainMethod = MethodDeclaration.CreateMainMethodDeclaration(new List<IStatement>(), 0, 0); var mainClass = ClassDeclaration.CreateMainClassDeclaration("Foo", mainMethod, 0, 0); var secondClass = new ClassDeclaration("Bar", null, new List<Declaration>(), 2, 0); var thirdClass = new ClassDeclaration("Baz", null, new List<Declaration>(), 3, 0); var program = new Program(mainClass, new List<ClassDeclaration>( new [] { secondClass, thirdClass })); var errorReporter = new ErrorLogger(); var builder = new SymbolTableBuilder(program, errorReporter); builder.BuildSymbolTable(); var types = (program.Scope as GlobalScope).UserDefinedTypeNames.ToList(); Assert.Contains("Foo", types); Assert.Contains("Bar", types); Assert.Contains("Baz", types); Assert.That(types, Is.Not.Contains("int")); Assert.That(types, Is.Not.Contains("boolean")); Assert.That(types.Count, Is.EqualTo(3)); }
public void ShouldConflictWithPredefinedTypesTest() { var mainMethod = MethodDeclaration.CreateMainMethodDeclaration(new List<IStatement>(), 0, 0); var mainClass = ClassDeclaration.CreateMainClassDeclaration("int", mainMethod, 1, 0); var secondClass = new ClassDeclaration("boolean", null, new List<Declaration>(), 2, 0); var thirdClass = new ClassDeclaration("int", null, new List<Declaration>(), 3, 0); var program = new Program(mainClass, new List<ClassDeclaration> ( new [] { secondClass, thirdClass })); var errorReporter = new ErrorLogger(); var builder = new SymbolTableBuilder(program, errorReporter); Assert.AreEqual(SymbolTableBuilder.ExitCode.FatalError, builder.BuildSymbolTable()); var errors = errorReporter.Errors; Assert.AreEqual(3, errors.Count); Assert.AreEqual("Conflicting definitions for int.", errors[0].Content); Assert.AreEqual(1, errors[0].Row); Assert.AreEqual("Conflicting definitions for boolean.", errors[1].Content); Assert.AreEqual(2, errors[1].Row); Assert.AreEqual("Conflicting definitions for int.", errors[2].Content); Assert.AreEqual(3, errors[2].Row); }
public override void Exit(ClassDeclaration node) { ExitScope(); }
// Detects references to unknown types in class inheritance // declarations. If the inherited type cannot be resolved, // InheritedType will remain null (instead of being set // to ErrorType). public override void Visit(ClassDeclaration node) { // Resolve inheritance relationships. var typeSymbol = CurrentScope.ResolveType(node.Name); if (node.InheritedClassName != null) { var inheritedType = (TypeSymbol) CurrentScope.ResolveType(node.InheritedClassName); if (inheritedType == null) { ReportTypeNameError(node.InheritedClassName, node); } else { typeSymbol.SuperClass = inheritedType; } } node.Scope = typeSymbol.Scope; typeSymbol.Declaration = node; EnterScope(typeSymbol.Scope); }
public override void Exit(ClassDeclaration node) { _currentType = null; }