private void CheckLevelAccessForMethods(MethodNameTableItem method, ITerminalNode routineToken, SlangCustomType classIdent) { foreach (var item in method.Params) { var typeArg = item.TypeArg.Type; if (typeArg is SlangCustomType || typeArg is SlangPointerType) { var customType = GetUserType(typeArg); var classItem = Table.Modules[customType.ModuleName].Classes[customType.Name]; if (classItem.AccessModifier == AccessModifier.Private && !customType.Equals(classIdent)) { ThrowLevelAccessibilityForRoutineException(routineToken, ModuleData.File, customType.ToString(), method.Name); } } } if (method.ReturnType != null) { if (method.ReturnType is SlangCustomType type) { var classItem = Table.Modules[type.ModuleName].Classes[type.Name]; if (classItem.AccessModifier == AccessModifier.Private) { ThrowLevelAccessibilityForRoutineException(routineToken, ModuleData.File, type.ToString(), method.Name); } } } }
private void TranslateMethodDecl(MethodNameTableItem method) { headerText.Write("virtual "); WriteRoutineHeader(headerText, method); if (method.IsAbstract) { headerText.Write(" = 0"); } headerText.WriteLine(";"); }
public static void ThrowClassMethodDoesNotOverrideException(MethodNameTableItem item, FileInfo file) => throw new CompilerException($"Method {item.Name} marked override but does not override", file, item.Line, item.Column);
public static void ThrowClassMethodNotMarkedOverrideException(MethodNameTableItem methodOverriden, FileInfo fileInfo) => throw new CompilerException($"Method {methodOverriden.Name} does not marked override", fileInfo, methodOverriden.Line, methodOverriden.Column);
private void ValidateContext(SLangGrammarParser.ThisHeaderContext thisHeader, ITerminalNode id, SLangGrammarParser.ImportHeadContext importHead, ITerminalNode accessModifier, ITerminalNode abstractToken, ITerminalNode overrideToken, SLangGrammarParser.RoutineArgListContext routineArgList, SLangGrammarParser.TypeNameContext typeName, SLangGrammarParser.StatementSeqContext statementSeq) { var isMethod = thisHeader != null; var symbol = id.Symbol; string nameOfThis = string.Empty; if (isMethod) { nameOfThis = thisHeader.Id().GetText(); ThrowIfReservedWord(nameOfThis, ModuleData.File, thisHeader.Id().Symbol); if (importHead != null) { ThrowImportHeaderMethodsException(ModuleData.File, id); } } var name = id.GetText(); ThrowIfReservedWord(name, ModuleData.File, symbol); var args = Visit(routineArgList) as List <RoutineArgNameTableItem>; ImportHeader header = null; if (importHead != null) { header = Visit(importHead) as ImportHeader; } SlangType returnType = typeName != null?Visit(typeName) as SlangType : null; var modifier = GetModifierByName(accessModifier.GetText()); var isAbstract = abstractToken != null; var isOverride = overrideToken != null; if (!isMethod && (isAbstract || isOverride)) { ThrowRoutinesAbstractOverrideException(ModuleData.File, abstractToken ?? overrideToken); } if (header != null && statementSeq.statement().Length != 0) { ThrowImportHeaderException(ModuleData.File, id); } if (isMethod) { if (Visit(thisHeader) is SlangCustomType methodTypeIdent && methodTypeIdent.ModuleName != ModuleData.Name) { ThrowModuleFromOtherClassModuleException(id, ModuleData.File); } if (isAbstract) { ThrowIfAbstractMethodPrivate(modifier, ModuleData.File, id); } if ((args ?? throw new InvalidOperationException(nameof(args))).Any(a => a.Name == nameOfThis)) { ThrowConfictsThisException(thisHeader.Id(), ModuleData.File); } var classData = Visit(thisHeader) as SlangCustomType; var foundClass = Table.FindClass(classData); if (foundClass.Methods.ContainsKey(name)) { ThrowMethodSignatureExistsException(classData, id, ModuleData.File); } if (isAbstract && statementSeq.statement().Length != 0) { ThrowAbstractEmptyException(id, ModuleData.File); } var method = new MethodNameTableItem { AccessModifier = modifier, Column = symbol.Column, Header = header, IsAbstract = isAbstract, IsOverride = isOverride, Line = symbol.Line, Name = name, NameOfThis = nameOfThis, Params = args, ReturnType = returnType }; if (modifier == AccessModifier.Public) { CheckLevelAccessForMethods(method, id, classData); } foundClass.CheckRoutineConflicts(moduleItem.ModuleData, method); foundClass.Methods.Add(method.Name, method); } else { if (moduleItem.Routines.ContainsKey(name)) { ThrowRoutineExistsException(id, ModuleData.File); } var routine = new RoutineNameTableItem { AccessModifier = modifier, Column = symbol.Column, Line = symbol.Line, Header = header, Name = name, Params = args, ReturnType = returnType }; if (modifier == AccessModifier.Public) { CheckLevelAccessForRoutines(routine, id, name); } moduleItem.CheckCommonNamesConflicts(routine.Name, routine.Line, routine.Column); moduleItem.Routines.Add(routine.Name, routine); } }