private void Check(CodeElement e, SymbolTable table, FunctionCall call, FunctionDeclaration definition) { var parameters = definition.Profile.Parameters; if (call.InputParameters.Count > parameters.Count) { var m = System.String.Format("Function {0} only takes {1} parameters", definition.Name, parameters.Count); DiagnosticUtils.AddError(e, m); } for (int c = 0; c < parameters.Count; c++) { var expected = parameters[c]; if (c < call.InputParameters.Count) { var actual = call.InputParameters[c]; if (actual.IsLiteral) continue; var found = table.GetVariable(new URI(actual.Value)); if (found.Count < 1) DiagnosticUtils.AddError(e, "Parameter "+actual.Value+" is not referenced"); if (found.Count > 1) DiagnosticUtils.AddError(e, "Ambiguous reference to parameter "+actual.Value); if (found.Count!= 1) continue; var type = found[0] as Typed; // type check. please note: // 1- if only one of [actual|expected] types is null, overriden DataType.!= operator will detect it // 2- if both are null, we WANT it to break: in TypeCobol EVERYTHING should be typed, // and things we cannot know their type as typed as DataType.Unknown (which is a non-null valid type). if (type == null || type.DataType != expected.DataType) { var m = System.String.Format("Function {0} expected parameter {1} of type {2} (actual: {3})", definition.Name, c+1, expected.DataType, type.DataType); DiagnosticUtils.AddError(e, m); } if (type != null && type.Length > expected.Length) { var m = System.String.Format("Function {0} expected parameter {1} of max length {2} (actual: {3})", definition.Name, c+1, expected.Length, type.Length); DiagnosticUtils.AddError(e, m); } } else { var m = System.String.Format("Function {0} is missing parameter {1} of type {2}", definition.Name, c+1, expected.DataType); DiagnosticUtils.AddError(e, m); } } }
public IList<Diagnostic> GetDiagnostics(CodeElement e) { var results = new List<Diagnostic>(); foreach(var d in e.Diagnostics) { var diagnostic = AsDiagnostic(d); if (e.ConsumedTokens.Count < 1) diagnostic.Range = Range.Unknown; else diagnostic.Range = GetRange(e.ConsumedTokens, d.ColumnStart, d.ColumnEnd); results.Add(diagnostic); } return results; }
/// <summary> /// Always use this method add new code element to this line (never call directly CodeElements.Add) /// </summary> internal void AddCodeElement(CodeElement codeElement) { // Lazy list instantiation if(CodeElements == null) { // In most cases, there will be no more than a single code element per line CodeElements = new List<CodeElement>(1); } CodeElements.Add(codeElement); }
/// <summary>Notifies listeners about the creation of a new CodeElement.</summary> public void OnCodeElement(CodeElement e, ParserRuleContext context) { foreach(var listener in _listeners) { var types = listener.GetCodeElements(); foreach (var expected in types) { if (Reflection.IsTypeOf(e.GetType(), expected)) { listener.OnCodeElement(e, context); break; // only notify each listener once for a given CodeElement } } } }
internal string ToJSON(int a, TypeCobol.Compiler.CodeElements.CodeElement e) { var b = new StringBuilder("\n").Append(i(a)).Append("{"); newline(b, a + 1, ""); kv(b, "Type", "\"" + e.Type + "\""); newline(b, a + 1, ","); b.Append("\"ConsumedTokens\": ["); bool first = true; foreach (var t in e.ConsumedTokens) { if (first) { newline(b, a + 3, ""); first = false; } else { newline(b, a + 3, ","); } b.Append(ToJSON(a + 3, t)); } newline(b, a + 1, ""); b.Append("]"); newline(b, a + 1, ","); b.Append("\"Diagnostics\": ["); first = true; if (e.Diagnostics != null) { foreach (var d in e.Diagnostics) { if (first) { newline(b, a + 3, ""); first = false; } else { newline(b, a + 3, ","); } b.Append(ToJSON(a + 3, d)); } } newline(b, a + 1, ""); b.Append("]"); newline(b, a, ""); return(b.Append("}").ToString()); }
private static void TestLine(CodeElement e, string line) { Console.WriteLine("TODO TestLine( " + e + " , \"" + line + "\")"); }
/// <summary> /// Apply propperties of the current CodeElement to the specified one. /// </summary> /// <param name="ce"></param> public void ApplyPropertiesToCE(CodeElement ce) { ce.ConsumedTokens = this.ConsumedTokens; ce.Diagnostics = this.Diagnostics; ce.SymbolInformationForTokens = this.SymbolInformationForTokens; }
private void checkReadOnly(CodeElement ce, Node receiving) { var rtype = receiving.Parent as Typed; if (rtype == null) return; foreach(var type in READONLY_DATATYPES) { if (type.Equals(rtype.DataType.Name.ToUpper())) DiagnosticUtils.AddError(ce, type+" properties are read-only"); } }
private void CheckParameter([NotNull] ParameterDescriptionEntry parameter, CodeElement ce, ParserRuleContext context) { // TCRFUN_LEVEL_88_PARAMETERS if (parameter.LevelNumber.Value != 1) { DiagnosticUtils.AddError(ce, "Condition parameter \""+parameter.Name+"\" must be subordinate to another parameter.", context); } if (parameter.DataConditions != null) { foreach (var condition in parameter.DataConditions) { if (condition.LevelNumber.Value != 88) DiagnosticUtils.AddError(ce, "Condition parameter \"" + condition.Name + "\" must be level 88."); } } }
private void CheckParameter(ParameterDescription parameter, CodeElement ce, ParserRuleContext context) { // TCRFUN_LEVEL_88_PARAMETERS if (parameter.CodeElement().LevelNumber.Value != 1) DiagnosticUtils.AddError(ce, "Condition parameter \""+parameter.Name+"\" must be subordinate to another parameter.", context); foreach(var child in parameter.Children) { var condition = (DataConditionEntry)child.CodeElement; if (condition.LevelNumber.Value != 88) DiagnosticUtils.AddError(ce, "Condition parameter \""+condition.Name+"\" must be level 88."); } }
private void CheckParameters(ParametersProfile profile, CodeElement ce, ParserRuleContext context) { foreach(var parameter in profile.InputParameters) CheckParameter(parameter, ce, context); foreach(var parameter in profile.InoutParameters) CheckParameter(parameter, ce, context); foreach(var parameter in profile.OutputParameters) CheckParameter(parameter, ce, context); if (profile.ReturningParameter != null) CheckParameter(profile.ReturningParameter, ce, context); }
internal static void AddError(CodeElement e, string message, MessageCode code = MessageCode.SyntaxErrorInParser) { e.Diagnostics.Add(new ParserDiagnostic(message, e.StartIndex+1, e.StopIndex+1, e.ConsumedTokens[0].Line, null, code)); }
internal static void AddError(CodeElement e, string message, Scanner.Token token, string rulestack = null, MessageCode code = MessageCode.SyntaxErrorInParser) { e.Diagnostics.Add(new ParserDiagnostic(message, token, rulestack, code)); }
public void OnCodeElement(CodeElement ce, ParserRuleContext context) { var function = (FunctionDeclarationHeader)ce; if (function.ActualType == FunctionType.Undefined) { DiagnosticUtils.AddError(ce, "Incompatible parameter clauses for "+ToString(function.UserDefinedType)+" \""+function.Name+"\"", context); } else if ( (function.ActualType == FunctionType.Function && function.UserDefinedType == FunctionType.Procedure) ||(function.ActualType == FunctionType.Procedure && function.UserDefinedType == FunctionType.Function) ) { var message = "Symbol \""+function.Name+"\" is defined as "+ToString(function.UserDefinedType) +", but parameter clauses describe a "+ToString(function.ActualType); DiagnosticUtils.AddError(ce, message, context); } }
private void CheckNotInTable(SymbolTable table, SymbolReference symbol, CodeElement ce) { if (symbol == null) return; string message = "TCRFUN_NO_PERFORM_OF_ENCLOSING_PROGRAM"; var found = table.GetSection(symbol.Name); if (found.Count > 0) DiagnosticUtils.AddError(ce, message); else { found = table.GetParagraph(symbol.Name); if (found.Count > 0) DiagnosticUtils.AddError(ce, message); } }
public IToken NextToken() { if(currentCodeElementIndexInLine >= 0) { currentCodeElementIndexInLine++; if(currentCodeElementIndexInLine < codeElementsLinesEnumerator.Current.CodeElements.Count) { currentToken = codeElementsLinesEnumerator.Current.CodeElements[currentCodeElementIndexInLine]; return currentToken; } else { currentCodeElementIndexInLine = -1; } } if (currentCodeElementIndexInLine < 0) { while(codeElementsLinesEnumerator.MoveNext()) { if(codeElementsLinesEnumerator.Current.CodeElements != null && codeElementsLinesEnumerator.Current.CodeElements.Count > 0) { currentCodeElementIndexInLine = 0; currentToken = codeElementsLinesEnumerator.Current.CodeElements[currentCodeElementIndexInLine]; return currentToken; } } } return Token.END_OF_FILE; }
/// <summary> /// Apply propperties of the current CodeElement to the specified one. /// </summary> /// <param name="ce"></param> public void ApplyPropertiesToCE([NotNull] CodeElement ce) { ce.ConsumedTokens = this.ConsumedTokens; ce.Diagnostics = this.Diagnostics; ce.SymbolInformationForTokens = this.SymbolInformationForTokens; }
public virtual bool Visit(CodeElement codeElement) { return(true); }
public virtual void EndCodeElement(CodeElement codeElement) { }
public virtual bool BeginCodeElement(CodeElement codeElement) { return(true); }
public Range GetRange(CodeElement e) { var start = e.ConsumedTokens[0].StartIndex; var end = e.ConsumedTokens[e.ConsumedTokens.Count-1].StopIndex; return GetRange(e.ConsumedTokens, start, end); }
internal static void AddError(CodeElement e, string message, Antlr4.Runtime.RuleContext context, MessageCode code = MessageCode.SyntaxErrorInParser) { AddError(e, message, ParseTreeUtils.GetFirstToken(context), new RuleStackBuilder().GetRuleStack(context), code); }