private void ProcessInternalMacro(InternalClass klass, MacroStatement node) { TypeDefinition macroDefinition = klass.TypeDefinition; if (MacroDefinitionContainsMacroApplication(macroDefinition, node)) { ProcessingError(CompilerErrorFactory.InvalidMacro(node, klass)); return; } var macroCompiler = My <MacroCompiler> .Instance; bool firstTry = !macroCompiler.AlreadyCompiled(macroDefinition); Type macroType = macroCompiler.Compile(macroDefinition); if (macroType == null) { if (firstTry) { ProcessingError(CompilerErrorFactory.AstMacroMustBeExternal(node, klass)); } else { RemoveCurrentNode(); } return; } ProcessMacro(macroType, node); }
public void MacroCompilerIsTakenFromTheEnvironment() { var compiler = new Mock <MacroCompiler>(MockBehavior.Strict); ActiveEnvironment.With(CompilerContextEnvironmentWith(compiler), () => { var module = CreateModule(); var macroApplication = new MacroStatement(new LexicalInfo("file.boo", 1, 1), "foo"); module.Globals.Add(macroApplication); var macroDefinition = CreateClassOn(module, "FooMacro"); compiler.Setup(o => o.AlreadyCompiled(macroDefinition)).Returns(false); compiler.Setup(o => o.Compile(macroDefinition)).Returns((Type)null); var expander = My <MacroExpander> .Instance; Assert.IsFalse(expander.ExpandAll()); var errors = CompilerErrors(); Assert.AreEqual(1, errors.Count); Assert.AreEqual(CompilerErrorFactory.AstMacroMustBeExternal(macroApplication, (IType)macroDefinition.Entity).ToString(), errors[0].ToString()); }); compiler.VerifyAll(); }
private void ProcessInternalMacro(InternalClass klass, MacroStatement node) { Type macroType = new MacroCompiler(Context).Compile(klass); if (null == macroType) { Errors.Add(CompilerErrorFactory.AstMacroMustBeExternal(node, klass.FullName)); return; } ProcessMacro(macroType, node); }
override public void OnMacroStatement(MacroStatement node) { Visit(node.Block); Visit(node.Arguments); Statement replacement = null; IEntity entity = NameResolutionService.ResolveQualifiedName(BuildMacroTypeName(node.Name)); if (null == entity) { entity = NameResolutionService.ResolveQualifiedName(node.Name); } if (null == entity) { Errors.Add(CompilerErrorFactory.UnknownMacro(node, node.Name)); } else { if (EntityType.Type != entity.EntityType) { Errors.Add(CompilerErrorFactory.InvalidMacro(node, node.Name)); } else { IType macroType = (IType)entity; ExternalType type = macroType as ExternalType; if (null == type) { Errors.Add(CompilerErrorFactory.AstMacroMustBeExternal(node, macroType.FullName)); } else { object macroInstance = Activator.CreateInstance(type.ActualType); if (!(macroInstance is IAstMacro)) { Errors.Add(CompilerErrorFactory.InvalidMacro(node, macroType.FullName)); } else { try { using (IAstMacro macro = ((IAstMacro)macroInstance)) { macro.Initialize(_context); replacement = macro.Expand(node); } } catch (Exception error) { Errors.Add(CompilerErrorFactory.MacroExpansionError(node, error)); } } } } } if (null != node.Modifier) { replacement = NormalizeStatementModifiers.CreateModifiedStatement(node.Modifier, replacement); } ReplaceCurrentNode(replacement); }