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);
     }
     }
 }
Beispiel #2
0
 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;
 }
Beispiel #3
0
        /// <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
             }
         }
     }
 }
Beispiel #5
0
        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());
        }
Beispiel #6
0
 private static void TestLine(CodeElement e, string line)
 {
     Console.WriteLine("TODO TestLine( " + e + " , \"" + line + "\")");
 }
Beispiel #7
0
 /// <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");
     }
 }
Beispiel #9
0
 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);
 }
Beispiel #12
0
 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));
 }
Beispiel #13
0
 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));
 }
Beispiel #14
0
 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);
     }
 }
Beispiel #15
0
 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;
        }
Beispiel #17
0
 /// <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;
 }
Beispiel #18
0
 public virtual bool Visit(CodeElement codeElement)
 {
     return(true);
 }
Beispiel #19
0
 public virtual void EndCodeElement(CodeElement codeElement)
 {
 }
Beispiel #20
0
 public virtual bool BeginCodeElement(CodeElement codeElement)
 {
     return(true);
 }
Beispiel #21
0
 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);
 }
Beispiel #22
0
 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);
 }