scriban / scriban

A fast, powerful, safe and lightweight scripting language and engine for .NET

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Function was not found

mrpmorris opened this issue · comments

I feel bad asking for help, but I am stuck :)

I have this struct

public readonly struct MoxyMeta
{
	public Type Class { get; init; }
}

I create an instance and add it as a variable to my context

var scribanScriptObject = TemplateContext.GetDefaultBuiltinObject();
				
var moxyMeta = new MoxyMeta {
	Class = classType
};
scribanScriptObject.Add(
	key: "moxy",
	value: moxyMeta);

When I try to build the following, it succeeds

{{ moxy.Class.Name }}

When I try to build the following, it fails

{{ moxy.Class.GetProperties().Length }}
Scriban.Syntax.ScriptRuntimeException: 'C:\Data\Mine\Code\Morris.Moxy\Source\Tutorials\01-MixInAMethod\MixInAMethod\Mixins\SayHello.mixin(9,15) : error : The function `moxy.Class.GetProperties` was not found'

   at Scriban.Syntax.ScriptFunctionCall.Evaluate(TemplateContext context)
   at Scriban.TemplateContext.Evaluate(ScriptNode scriptNode, Boolean aliasReturnedFunction)
   at Scriban.TemplateContext.GetOrSetValue(ScriptExpression targetExpression, Object valueToSet, Boolean setter)
   at Scriban.TemplateContext.GetValue(ScriptExpression target)
   at Scriban.Syntax.ScriptMemberExpression.GetTargetObject(TemplateContext context, Boolean isSet)
   at Scriban.Syntax.ScriptMemberExpression.GetValue(TemplateContext context)
   at Scriban.TemplateContext.GetOrSetValue(ScriptExpression targetExpression, Object valueToSet, Boolean setter)
   at Scriban.TemplateContext.GetValue(ScriptExpression target)
   at Scriban.TemplateContext.Evaluate(ScriptNode scriptNode, Boolean aliasReturnedFunction)
   at Scriban.Syntax.ScriptExpressionStatement.Evaluate(TemplateContext context)
   at Scriban.TemplateContext.Evaluate(ScriptNode scriptNode, Boolean aliasReturnedFunction)
   at Scriban.Syntax.ScriptBlockStatement.Evaluate(TemplateContext context)
   at Scriban.TemplateContext.Evaluate(ScriptNode scriptNode, Boolean aliasReturnedFunction)
   at Scriban.Syntax.ScriptPage.Evaluate(TemplateContext context)
   at Scriban.TemplateContext.Evaluate(ScriptNode scriptNode, Boolean aliasReturnedFunction)
   at Scriban.Template.EvaluateAndRender(TemplateContext context, Boolean render)
   at Scriban.Template.Render(TemplateContext context)
   at Morris.Moxy.Classes.ClassesSourceGenerator.TryGenerateSource(SourceProductionContext productionContext, Compilation compilation, MetadataLoadContext reflection, String projectPath, ImmutableArray`1 classInfos, ImmutableDictionary`2 nameToCompiledTemplateLookup) in C:\Data\Mine\Code\Morris.Moxy\Source\Lib\Morris.Moxy\Classes\ClassesSourceGenerator.cs:line 82

I added a member renamer so I could see which members are being picked up, and none seem to be methods.

var scribanTemplateContext = new TemplateContext(scribanScriptObject) {
	MemberRenamer = m => m.Name
};

Could you tell me how to execute methods on .net objects? I need to call Type.GetProperties() etc.

Thank you!

When I try to build the following, it fails
{{ moxy.Class.GetProperties().Length }}

That's by design, instance methods are not supported in Scriban (for sandboxing reason).

I had a look at the doc, thought it was clearly mentioned, but only what is supported is mentioned here

Note that for security reason, only the properties of .NET objects accessed through another ScriptObject are made accessible from a Template. Methods and static methods are not automatically imported.

Scriban is really not made to give full access to .NET. If you are getting into such details, you might have to use e.g Razor for example.

Thanks for your (very) quick response!

None of the methods I am calling alter state, they are all reflection. Is there a way I can register them?

None of the methods I am calling alter state, they are all reflection. Is there a way I can register them?

You need to wrap them with a function that you can import, e.g :

scriptObject.Import("my_function", new Action(() => ...));