/// <summary> /// Resolves literal value of <see cref="Alias"/>. /// </summary> /// <param name="alias">Instance of <see cref="Alias"/>.</param> /// <param name="valueType">Value type of the resolved literal.</param> /// <returns>String representing literal value of the <see cref="Alias"/>.</returns> protected string ResolveValueAlias(Alias alias, out ValueType valueType) { var aliasDef = alias.AliasDefinition; AliasContext.Push(new AliasContextInfo(alias, CurrentModuleMember)); CurrentModuleMember = aliasDef; string result; if (aliasDef.ValueType == ValueType.LiteralChoice) { result = ResolveChoiceValue(alias, out valueType); } else { result = aliasDef.PairValue == null ? ResolveValue(aliasDef, out valueType) : ResolvePairValue(aliasDef.PairValue, out valueType); } CurrentModuleMember = AliasContext.Pop().ModuleMember; return(result); }
/// <summary> /// Tells <see cref="NamespaceResolver"/> to check validity of <see cref="Alias"/> and add it /// to the list of aliases of the current <see cref="ModuleMember"/>. /// Method should be called from the visitor. /// </summary> /// <param name="alias">The alias to be added.</param> public void ProcessAlias(Alias alias) { CheckDuplicateArguments(alias); // Adds Alias to the Namespace Info of the current Module Member. CurrentModuleMemberNsInfo.Aliases.Add(alias); }
/// <summary> /// Ensures that pair value is either Alias or Parameter. /// Validates string concatenation. /// </summary> /// <param name="pair"></param> private void CheckPairValue(Pair pair) { if (pair.Delimiter == DelimiterEnum.CE) { if (pair.PairValue == null || !(pair.PairValue is DOM.Alias) && !(pair.PairValue is DOM.Parameter)) { var mappedPair = pair.PairValue as IMappedPair; Context.AddError(mappedPair != null ? CompilerErrorFactory.AliasOrParameterExpected(mappedPair.NameInterval, _currentModule.FileName) : CompilerErrorFactory.AliasOrParameterExpected(((IMappedPair)pair).NameInterval, _currentModule.FileName)); } else { Visit(pair.PairValue); } } else if (pair.Delimiter == DelimiterEnum.EC) { CheckStringConcatenation(pair); } if (pair.PairValue is DOM.Parameter) { var aliasContext = AliasContext.Peek(); if (aliasContext != null) { ValidateParameter((Parameter)pair.PairValue, aliasContext.Alias, _currentModule.FileName); } } else if (pair.PairValue is DOM.Alias) { Alias alias = (Alias)pair.PairValue; CheckAliasIsDefined(alias); var aliasDef = alias.AliasDefinition; //Do not resolve alias without AliasDef or having circular reference if (aliasDef == null || aliasDef.HasCircularReference) { return; } AliasContext.Push(new AliasContext() { AliasDefinition = aliasDef, Alias = alias, AliasNsInfo = GetContextNsInfo() }); CheckForUnexpectedArguments(alias, aliasDef, _currentModule.FileName); CheckInterpolation(aliasDef); CheckPairValue(aliasDef); if (CheckStartOfChoiceContainer(alias, aliasDef.Entities, aliasDef)) { Visit(aliasDef.Entities.Where(e => !(e is DOM.Attribute))); EndChoiceContainer(/*aliasDef, aliasDef.Entities*/); } else { Visit(aliasDef.Entities.Where(e => !(e is DOM.Attribute))); } AliasContext.Pop(); } }
private void CheckForUnexpectedArguments(Alias alias, AliasDefinition aliasDef, string fileName) { foreach (var argument in alias.Arguments) { if (aliasDef.Parameters.All(p => p.Name != argument.Name)) { Context.AddError(CompilerErrorFactory.UnexpectedArgument((Argument)argument, fileName)); } } if (!aliasDef.HasDefaultBlockParameter) { if (alias.Entities.Any(e => !(e is Comment) && e is IMappedPair mp && (mp.BlockType == BlockType.Default || mp.BlockType == BlockType.JsonArray))) { Context.AddError( CompilerErrorFactory.UnexpectedDefaultBlockArgument((IMappedPair)alias.Entities[0], fileName)); } } if (!aliasDef.HasDefaultValueParameter && alias.HasValue()) { Context.AddError(CompilerErrorFactory.UnexpectedDefaultValueArgument(alias, fileName)); } }
private void CheckDuplicateArguments(Alias alias) { var dups = alias.Arguments.GroupBy(a => a.Name).Where(g => g.Count() > 1).SelectMany(g => g).ToList(); dups.ForEach( a => _context.AddError(CompilerErrorFactory.DuplicateArgumentName((Argument)a, _currentModule.FileName))); }
private int CalcNumOfRootElements(Alias alias) { int result = 0; var aliasDef = alias.AliasDefinition; if (aliasDef == null) { return(0); } if (aliasDef.HasCircularReference) { return(0); } PairCollection <Entity> entities = null; if (aliasDef.Delimiter == DelimiterEnum.CC) { var choiceInfo = JsonGenerator.FindChoiceInfo(_choiceStack.Peek(), alias); if (choiceInfo?.Children != null) { entities = ((Element)choiceInfo.Children[0].ChoiceNode).Entities; } } else { entities = aliasDef.Entities; } if (entities == null) { return(result); } foreach (var entity in entities) { if (entity is DOM.Element) { result++; continue; } var scopeEntity = entity as Scope; if (scopeEntity != null) { result += CalcNumOfRootElements(scopeEntity); continue; } var aliasEntity = entity as DOM.Alias; if (aliasEntity != null) { result += CalcNumOfRootElements((Alias)aliasEntity); continue; } } return(result); }
private void CheckCompatibilityWithParameters(Alias alias, AliasDefinition aliasDef, string fileName) { foreach (var parameter in aliasDef.Parameters) { if (parameter.Name == "_") //Default parameter { if (!parameter.IsValueNode) { if (alias.Entities.All(e => e is Comment) && alias.ValueType != ValueType.Object) { ReportErrorInsideChoice(() => CompilerErrorFactory.DefaultBlockArgumentIsMissing(alias, fileName)); } } else { if (parameter.HasValue()) { continue; //if parameter has default value then skip check } if (!alias.HasValue()) { ReportErrorInsideChoice(() => CompilerErrorFactory.DefaultValueArgumentIsMissing(alias, fileName)); } } continue; } //Non default parameter var argument = alias.Arguments.FirstOrDefault(a => a.Name == parameter.Name); if (argument == null) { //Report Error if argument is missing and there is no default value for the parameter if (parameter.Value == null && parameter.Entities.Count == 0 && parameter.ValueType != ValueType.Object) { ReportErrorInsideChoice(() => CompilerErrorFactory.ArgumentIsMissing(alias, parameter.Name, fileName)); } continue; } //Report error if type of argument (value/block) mismatch the type of parameter if (((Argument)argument).IsValueNode != parameter.IsValueNode) { ReportErrorInsideChoice(() => parameter.IsValueNode ? CompilerErrorFactory.ValueArgumentIsExpected((Argument)argument, fileName) : CompilerErrorFactory.BlockArgumentIsExpected((Argument)argument, fileName)); } } }
private void ValidateParameter(Parameter parameter, Alias alias, string moduleFileName) { if (parameter.Name == "_") //Default parameter { if (!parameter.IsValueNode) { if (alias.Entities.All(e => e is Comment) && !alias.Assignment.IsObjectAssignment()) { ReportErrorInsideChoice(() => CompilerErrorFactory.DefaultBlockArgumentIsMissing(alias, moduleFileName)); } } else { if (parameter.HasValue()) { return; //if parameter has default value then skip check } if (!alias.HasValue()) { ReportErrorInsideChoice(() => CompilerErrorFactory.DefaultValueArgumentIsMissing(alias, moduleFileName)); } } return; } //Non default parameter var argument = alias.Arguments.FirstOrDefault(a => a.Name == parameter.Name); if (argument == null) { //Report Error if argument is missing and there is no default value for the parameter if (parameter.Value == null && parameter.Entities.Count == 0 && !parameter.Assignment.IsObjectAssignment()) { ReportErrorInsideChoice(() => CompilerErrorFactory.ArgumentIsMissing(alias, parameter.Name, moduleFileName)); } return; } //Report error if type of argument (value/block) mismatch the type of parameter if (((Argument)argument).IsValueNode != parameter.IsValueNode) { ReportErrorInsideChoice(() => parameter.IsValueNode ? CompilerErrorFactory.ValueArgumentIsExpected((Argument)argument, moduleFileName) : CompilerErrorFactory.BlockArgumentIsExpected((Argument)argument, moduleFileName)); } }
/// <summary> /// Resolves attributes in <see cref="Alias"/>. Elements are ignored. /// </summary> /// <param name="alias">Instance of <see cref="Alias"/>.</param> protected void ResolveAttributesInAlias(Alias alias) { var aliasDef = alias.AliasDefinition; //Do not resolve alias without AliasDef or having circular reference if (aliasDef == null || aliasDef.HasCircularReference) { return; } AliasContext.Push(new AliasContextInfo(alias, CurrentModuleMember)); CurrentModuleMember = aliasDef; ResolveAttributes(aliasDef.Entities); CurrentModuleMember = AliasContext.Pop().ModuleMember; }
protected virtual AliasDefinition LookupAliasDef(Alias alias) { if (alias.AliasDefinition != null && _syncTime <= alias.AliasDefinition.SyncTime) { return(alias.AliasDefinition); } var result = GetAliasDefinition(alias.Name); if (result != null) { result.SyncTime = _syncTime; } alias.AliasDefinition = result; return(result); }
protected void ResolveAttributesInAlias(Alias alias) { var aliasDef = alias.AliasDefinition; //Do not resolve alias without AliasDef or having circular reference if (aliasDef == null || aliasDef.HasCircularReference) { return; } AliasContext.Push(new AliasContext() { AliasDefinition = aliasDef, Alias = alias, AliasNsInfo = GetContextNsInfo() }); ResolveAttributes(aliasDef.Entities); AliasContext.Pop(); }
private NsInfo ResolveAliasInModuleMember(Alias alias, NsInfo memberNsInfo) { //Finding AliasDef var aliasDef = LookupAliasDef(alias); if (aliasDef == null) { //Report Error if alias is not defined //_context.AddError(CompilerErrorFactory.AliasIsNotDefined(alias, memberNsInfo.ModuleMember.Module.FileName)); return(null); } if (aliasDef.IsValueNode != alias.IsValueNode && alias.IsValueNode) { _context.AddError(CompilerErrorFactory.CantUseBlockAliasAsValue(alias, memberNsInfo.ModuleMember.Module.FileName)); } return(ResolveAliasesInAliasDefinition(aliasDef)); }
private static Alias GetAliasInterpolationItem(Match match, int line, int column, CompilerContext context, Module module) { if (match.Value.StartsWith(@"\$(") && !match.Value.EndsWith(@")")) { context.Errors.Add(CompilerErrorFactory.ParserError("Missing closing parenthesis.", module.FileName, line, column + match.Length)); } var alias = new Alias ( name: match.Value.TrimStart('\\', '$', '(', '\t', ' ').TrimEnd(')', '\t', ' '), nameInterval: new Interval(new CharLocation(line, column, -1), new CharLocation(line, column + match.Value.Length, -1)), assignment: AssignmentEnum.None, value: null, valueType: ValueType.Empty, isValueNode: true ); return(alias); }
protected string ResolveValueAlias(Alias alias, out ValueType valueType) { var aliasDef = NamespaceResolver.GetAliasDefinition(alias.Name); AliasContext.Push(new AliasContext { AliasDefinition = aliasDef, Alias = alias, AliasNsInfo = GetContextNsInfo() }); string result; if (aliasDef.ValueType == ValueType.LiteralChoice) { result = ResolveChoiceValue(alias, out valueType); } else { result = aliasDef.PairValue == null?ResolveNodeValue(aliasDef, out valueType) : ResolvePairValue(aliasDef.PairValue, out valueType); } AliasContext.Pop(); return(result); }
internal static CompilerError InvalidUsageOfValueAlias(Alias alias, string fileName) { return(Instantiate("MCE0016", new LexicalInfo(fileName, alias.NameInterval.Begin.Line, alias.NameInterval.Begin.Column, alias.NameInterval.Begin.Index), false)); }
/// <summary> /// Creates instance of the class. /// </summary> /// <param name="alias">Current alias.</param> /// <param name="currentModuleMember">Current module member.</param> public AliasContextInfo(Alias alias, ModuleMember currentModuleMember) { Alias = alias; ModuleMember = currentModuleMember; }
/// <inheritdoc /> public Pair CreateMappedPair(ITextSource textSource, int nameQuotesType, Interval nameInterval, AssignmentEnum assignment, Interval assignmentInterval, int valueQuotesType, Interval valueInterval, int valueIndent) { IMappedPair pair; var nameText = GetNameText(textSource, nameQuotesType, nameInterval); var value = GetValue(textSource, assignment, valueQuotesType, valueInterval, valueIndent, _context, _module); if (nameQuotesType > 0) { pair = new Element ( VerifyElementName(nameText, nameInterval, _module), nameQuotesType: nameQuotesType, nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } else if (nameText.StartsWith("@")) { var tuple = Element.GetNameAndNs(nameText.Substring(1), nameQuotesType); var ns = string.IsNullOrEmpty(tuple.Item1) ? null : tuple.Item1; pair = new Attribute ( VerifyName(tuple.Item2, nameInterval, _module), ns, nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } else if (nameText.StartsWith("!$")) { pair = new AliasDefinition ( VerifyName(nameText.Substring(2), nameInterval, _module), nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } else if (nameText.StartsWith("!#")) { pair = new NamespaceDefinition ( VerifyNsName(nameText.Substring(2), nameInterval, _module), nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } else if (nameText.StartsWith("!%")) { pair = new Parameter ( VerifyNsName(nameText.Substring(2), nameInterval, _module), nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } else if (nameText.StartsWith("!")) { pair = new Document ( VerifyName(nameText.Substring(1), nameInterval, _module), nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } else if (nameText.StartsWith("$")) { pair = new Alias ( VerifyName(nameText.Substring(1), nameInterval, _module), nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } else if (nameText.StartsWith("%")) { pair = new Argument ( VerifyName(nameText.Substring(1), nameInterval, _module), nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } else if (nameText.StartsWith("#")) { var tuple = Element.GetNameAndNs(nameText.Substring(1), nameQuotesType); var ns = string.IsNullOrEmpty(tuple.Item1) ? null : tuple.Item1; if (ns == null) { pair = new Scope ( null, VerifyScopeName(nameText.Substring(1), nameInterval, _module), nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } else { pair = new Scope ( VerifyElementName(tuple.Item2, nameInterval, _module), VerifyScopeName(ns, nameInterval, _module), nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } } else { var tuple = Element.GetNameAndNs(nameText, nameQuotesType); var ns = string.IsNullOrEmpty(tuple.Item1) ? null : tuple.Item1; pair = new Element ( VerifyElementName(tuple.Item2, nameInterval, _module), VerifyScopeName(ns, nameInterval, _module), nameInterval: nameInterval, assignment: assignment, assignmentInterval: assignmentInterval, value: value.Item1, valueQuotesType: valueQuotesType, valueInterval: valueInterval, interpolationItems: value.Item2, valueIndent: valueIndent, valueType: GetValueType(assignment, value.Item1, valueQuotesType) ); } return((Pair)pair); }
public void ProcessAlias(Alias node) { CheckDuplicateArguments(node); }
/// <summary> /// Adds Alias to the Namespace Info of the current Module Member. /// </summary> /// <param name="node"></param> public void AddAlias(Alias node) { CurrentModuleMemberNsInfo.Aliases.Add(node); }
internal static CompilerError ArgumentIsMissing(Alias alias, string argumentName, string fileName) { return(Instantiate("MCE0013", new LexicalInfo(fileName, alias.NameInterval.Begin.Line, alias.NameInterval.Begin.Column, alias.NameInterval.Begin.Index), false, argumentName)); }
internal static CompilerError CantUseBlockAliasAsValue(Alias alias, string fileName) { return(Instantiate("MCE0017", new LexicalInfo(fileName, alias.NameInterval.Begin.Line, alias.NameInterval.Begin.Column, alias.NameInterval.Begin.Index), false)); }
internal static CompilerError AliasIsNotDefined(Alias alias, string fileName) { return(Instantiate("MCE0004", new LexicalInfo(fileName, alias.NameInterval.Begin.Line, alias.NameInterval.Begin.Column, alias.NameInterval.Begin.Index), false, alias.Name)); }
public static CompilerError UnexpectedDefaultValueArgument(Alias alias, string fileName) { return(Instantiate("MCE0027", new LexicalInfo(fileName, alias.NameInterval.Begin.Line, alias.NameInterval.Begin.Column, alias.NameInterval.Begin.Index), false)); }
public static CompilerError DefaultBlockArgumentIsMissing(Alias alias, string fileName) { return(Instantiate("MCE0023", new LexicalInfo(fileName, alias.NameInterval.Begin.Line, alias.NameInterval.Begin.Column, alias.NameInterval.Begin.Index), false)); }