/// <summary> /// Gets the method to override. /// </summary> /// <param name="macro">The macro.</param> /// <returns></returns> private MethodInfo GetMethodToOverride(Node macro) { MethodInfo overridenMethod = null; if (blockMethodName != null) { try { overridenMethod = typeof(T).GetMethod(blockMethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); } catch (AmbiguousMatchException) { string msg = typeof(T).Name + " has more than one overload for method " + blockMethodName; Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, msg)); } catch (Exception exception) { string msg = string.Format("Error occured when trying to get method '{0}' on {1}. {2}", blockMethodName, typeof(T).Name, exception); Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, msg)); } if (overridenMethod == null) { Errors.Add( CompilerErrorFactory.CustomError(macro.LexicalInfo, "Could not find " + blockMethodName + " on " + typeof(T).FullName)); } } return(overridenMethod); }
public bool InitializeExtension(MethodInvocationExpression extension, MacroStatement macro, CompilerErrorCollection compileErrors) { _extension = extension; _compileErrors = compileErrors; if (macro.Body.IsEmpty) { if (macro.Arguments.Count != 1 || (ExtractMethod(macro.Arguments[0]) == false && _instanceAcessor == null)) { _compileErrors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "A createUsing statement must be in the form (@factory.<CreateMethod> | InstanceMethod)")); return(false); } ConfigureFactoryAccessor(); } else { ConfigureFactoryMethod(macro); } return(true); }
/// <summary> /// Perform the actual expansion of the macro /// </summary> /// <param name="macro">The macro.</param> /// <returns></returns> protected override Statement DoExpand(MacroStatement macro) { if (macro.Arguments.Count != 0) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "No arguments allowed for action statement")); return(null); } Method mergeRowsMethod = new Method("MergeRows"); mergeRowsMethod.Modifiers = TypeMemberModifiers.Override; mergeRowsMethod.Parameters.Add(new ParameterDeclaration("left", new SimpleTypeReference(typeof(Row).FullName))); mergeRowsMethod.Parameters.Add(new ParameterDeclaration("right", new SimpleTypeReference(typeof(Row).FullName))); CodeBuilder.DeclareLocal(mergeRowsMethod, "row", TypeSystemServices.Map(typeof(Row))); mergeRowsMethod.Body.Add( new BinaryExpression(BinaryOperatorType.Assign, new ReferenceExpression("row"), new MethodInvocationExpression( AstUtil.CreateReferenceExpression(typeof(Row).FullName)) ) ); mergeRowsMethod.Body.Add(macro.Body); mergeRowsMethod.Body.Add(new ReturnStatement(new ReferenceExpression("row"))); ParentMethods.Add(mergeRowsMethod); return(null); }
/// <summary> /// Perform the actual expansion of the macro /// </summary> /// <param name="macro">The macro.</param> /// <returns></returns> protected override Statement DoExpand(MacroStatement macro) { List <string> columns = new List <string>(); if (!macro.Body.IsEmpty) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "GroupBy cannot contain statements")); return(null); } foreach (Expression argument in macro.Arguments) { ReferenceExpression expr = argument as ReferenceExpression; if (expr == null) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "GroupBy arguments must be refernce expressions. Example: groupBy name, surname")); return(null); } columns.Add(expr.Name); } Method method = CreateGetColumnsToGroupByMethod(macro, columns); ParentMethods.Add(method); return(null); }
private Expression CreateBuilderIfNeeded(MethodInvocationExpression child, string name) { int argsCount = child.Arguments.Count; if (argsCount >= 1) { ReferenceExpression builder = child.Arguments[0] as ReferenceExpression; if (builder != null) { Block block; if (argsCount > 2 || (argsCount == 2 && !MacroHelper.IsNewBlock(child, out block))) { _compileErrors.Add(CompilerErrorFactory.CustomError( child.Arguments[0].LexicalInfo, "Builder syntax must be in the format builder, prop: value,...")); return(null); } MethodInvocationExpression builderCtor = new MethodInvocationExpression(builder); builderCtor.Arguments.Add(new StringLiteralExpression(name)); builderCtor.NamedArguments.Extend(child.NamedArguments); return(builderCtor); } } return(new StringLiteralExpression(name)); }
/// <summary> /// Expands the specified macro. /// </summary> /// <param name="macro">The macro.</param> /// <returns></returns> public override Statement Expand(MacroStatement macro) { var property = new Property(propertyName); property.LexicalInfo = macro.LexicalInfo; property.Getter = new Method(); if (macro.Arguments.Count == 1) { property.Getter.Body.Add( new ReturnStatement(macro.Arguments[0]) ); } else if ( macro.Arguments.Count == 0 && macro.Body != null && macro.Body.IsEmpty == false) //use the macro block { property.Getter.Body = macro.Body; } else { CompilerErrorFactory.CustomError(macro.LexicalInfo, macro.Name + " must have a single expression argument or a block"); return(null); } var clazz = (ClassDefinition)macro.GetAncestor(NodeType.ClassDefinition); clazz.Members.Add(property); return(null); }
public bool InitializeExtension(MethodInvocationExpression extension, MacroStatement macro, CompilerErrorCollection compileErrors) { _extension = extension; _compileErrors = compileErrors; if (macro.Arguments.Count != 1 || (!ExtractMethod(macro.Arguments[0]) && _instanceAcessor == null)) { _compileErrors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "A createUsing statement must be in the form @factory.<CreateMethod>[()]")); return(false); } if (_instanceAcessor == null) { _extension.Arguments.Add(Component); _extension.Arguments.Add(Method); } else { _extension.Arguments.Add(_instanceAcessor); } return(true); }
/// <summary> /// Perform the actual expansion of the macro /// </summary> /// <param name="macro">The macro.</param> /// <returns></returns> protected override Statement DoExpand(MacroStatement macro) { Block body = (Block)macro.GetAncestor(NodeType.Block); MacroStatement macroParent = (MacroStatement)macro.GetAncestor(NodeType.MacroStatement); if (macro.Body.Statements.Count < 1 && parent.Name == "join") { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Join " + name + " section must contain at least a single expression statement")); return(null); } if (macro.Arguments.Count == 0 && parent.Name != "join") { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Join " + name + " section must contain at least one key column")); return(null); } if (macro.Arguments.Count > 0) { ArrayLiteralExpression ale = new ArrayLiteralExpression(macro.LexicalInfo); ale.Type = new ArrayTypeReference(CodeBuilder.CreateTypeReference(typeof(string))); foreach (Expression argument in macro.Arguments) { ReferenceExpression expr = argument as ReferenceExpression; if (expr == null) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Join " + name + " section arguments must be reference expressions. Example: " + name + " name, surname")); return(null); } ale.Items.Add(new StringLiteralExpression(expr.Name)); } var keyExpr = new BinaryExpression(BinaryOperatorType.Assign, new ReferenceExpression(name + "KeyColumns"), ale); macroParent.Arguments.Add(keyExpr); } foreach (Statement statement in macro.Body.Statements) { ExpressionStatement exprStmt = statement as ExpressionStatement; if (exprStmt == null) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Join " + name + " section can only contain expressions")); return(null); } Expression expr = exprStmt.Expression; parent.Arguments.Add(new MethodInvocationExpression(new ReferenceExpression(name), expr)); } return(null); }
private bool BuildHashConfiguration(Block block) { _skip = false; _applied = true; if (!block.IsEmpty) { for (int i = 0; i < block.Statements.Count;) { var statement = block.Statements[i]; var expression = statement as ExpressionStatement; if (expression == null) { _compileErrors.Add(CompilerErrorFactory.CustomError( statement.LexicalInfo, "Unrecgonized configuration syntax")); return(false); } _found = false; Visit(expression.Expression); if (_found == false) { _compileErrors.Add(CompilerErrorFactory.CustomError( expression.LexicalInfo, "Unrecgonized configuration syntax")); return(false); } if (_applied) { if (_skip == false) { block.Statements.RemoveAt(i); } else { ++i; } } else { return(false); } } } return(true); }
private bool BuildAttribute(Expression expression, HashLiteralExpression configuration) { BinaryExpression attribute; if (MacroHelper.IsAssignment(expression, out attribute)) { BuildConfigurationNode(attribute, true, configuration); } else { _compileErrors.Add(CompilerErrorFactory.CustomError(expression.LexicalInfo, "Attributes must be in the format @attrib1=value1, attrib2=value2,...")); return(false); } return(true); }
override public Statement Expand(MacroStatement macro) { if (1 != macro.Arguments.Count || 0 != macro.Block.Statements.Count) { Errors.Add( CompilerErrorFactory.CustomError(macro.LexicalInfo, "yieldAll <expression>")); return(null); } ForStatement fs = new ForStatement(macro.LexicalInfo); fs.Declarations.Add(new Declaration(macro.LexicalInfo, "___item")); fs.Iterator = macro.Arguments[0]; fs.Block.Add( new YieldStatement(macro.LexicalInfo, new ReferenceExpression("___item"))); return(fs); }
public bool GetNode(Expression expression, bool asAttribute, CompilerErrorCollection compileErrors) { _isAttribute = asAttribute; _compileErrors = compileErrors; Visit(expression); if (_node == null) { _compileErrors.Add(CompilerErrorFactory.CustomError(expression.LexicalInfo, "Unrecgonized configuration node syntax")); return(false); } return(true); }
private void CreateMethodFromMacroBlock(MacroStatement macro, TypeDefinition classDefinition) { MethodInfo methodToOverride = GetMethodToOverride(macro); if (macro.Body != null && macro.Body.Statements.Count > 0) { if (methodToOverride == null) { Errors.Add( CompilerErrorFactory.CustomError(macro.LexicalInfo, MacroName + " cannot be use with a block")); } Method method = new Method(blockMethodName); method.Modifiers = TypeMemberModifiers.Override; method.Body = macro.Body; classDefinition.Members.Add(method); method.Parameters.Extend(BuildParameters(methodToOverride)); } }
/// <summary> /// Gets the name of the class that we will generate /// </summary> /// <param name="macro">The macro.</param> /// <returns></returns> protected virtual string GetClassName(MacroStatement macro) { if (macro.Arguments.Count == 0 || (macro.Arguments[0] is ReferenceExpression) == false) { return(GetAnonymousClassName(macro)); } argumentStartIndex = 1; ReferenceExpression referenceExpression = macro.Arguments[0] as ReferenceExpression; if (referenceExpression == null) { Errors.Add( CompilerErrorFactory.CustomError(macro.LexicalInfo, GetType().Name + " first parameter must be a valid name.")); return(null); } return(referenceExpression.Name); }
/// <summary> /// Gets the name of the anonymous class. /// </summary> /// <param name="macro">The macro.</param> /// <returns></returns> private string GetAnonymousClassName(MacroStatement macro) { if (macro.GetAncestor(NodeType.MacroStatement) == null) { Errors.Add( CompilerErrorFactory.CustomError(macro.LexicalInfo, GetType().Name + " must have a single parameter, the name of the " + GetType().Name)); return(null); } isAnonymous = true; string name = typeof(T).Name.Replace("Abstract", "").Replace("Operation", ""); if (macro["anonymous_name_index"] == null) { macro["anonymous_name_index"] = Context.GetUniqueName(); } return("Anonymous_" + name + "_" + macro["anonymous_name_index"]); }
private bool ValidateParent(MacroStatement macro, out MacroStatement parent) { parent = macro.ParentNode.ParentNode as MacroStatement; if (parent != null) { foreach (string validParent in allowedParents) { if (parent.Name.Equals(validParent, StringComparison.InvariantCultureIgnoreCase)) { return(true); } } } string msg = string.Format("A {0} statement can appear only under a {1}", macro.Name, string.Join(" | ", allowedParents)); Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, msg)); return(false); }
/// <summary> /// Perform the actual expansion of the macro /// </summary> /// <param name="macro">The macro.</param> /// <returns></returns> protected override Statement DoExpand(MacroStatement macro) { Block body = (Block)macro.GetAncestor(NodeType.Block); if (macro.Body.Statements.Count < 1) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Join" + name + " section must contain at least a single expression statement")); return(null); } foreach (Statement statement in macro.Body.Statements) { ExpressionStatement exprStmt = statement as ExpressionStatement; if (exprStmt == null) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Join" + name + " section can only contain expressions")); return(null); } Expression expr = exprStmt.Expression; MethodInvocationExpression expression = new MethodInvocationExpression(new ReferenceExpression(name), expr); body.Add(new ExpressionStatement(expression)); } return(null); }
/// <summary> /// Expands the specified macro /// </summary> /// <param name="macro">The macro.</param> /// <returns></returns> public override Statement Expand(MacroStatement macro) { ICollection <StringLiteralExpression> leftKeys = null; ICollection <StringLiteralExpression> rightKeys = null; foreach (var arg in macro.Arguments) { BinaryExpression assignment; if (!TryGetAssignment(arg, out assignment)) { continue; } var rf = assignment.Left as ReferenceExpression; if (rf == null) { continue; } var val = assignment.Right as ArrayLiteralExpression; if (val == null) { continue; } if (rf.Name != "RightKeyColumns" && rf.Name != "LeftKeyColumns") { continue; } var lst = Enumerable.OfType <StringLiteralExpression>(val.Items).ToList(); if (rf.Name == "RightKeyColumns") { rightKeys = lst; } else { leftKeys = lst; } } if (leftKeys == null || leftKeys.Count == 0) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "LeftKeys must be defined for a hash join")); return(null); } if (rightKeys == null || rightKeys.Count == 0) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "RightKeys must be defined for a hash join")); return(null); } if (rightKeys.Count != leftKeys.Count) { Errors.Add(CompilerErrorFactory.CustomError(macro.LexicalInfo, "Number of key columns must be the same for both sides of the join")); } var method = SetupJoinMethodDefinition(leftKeys, rightKeys); AddMethodDefinitionToClassDefinition(macro, method); return(base.Expand(macro)); }
protected void AddCompilerError(LexicalInfo lexicalInfo, string msg) { Errors.Add(CompilerErrorFactory.CustomError(lexicalInfo, msg)); }