/// <summary> /// Processes @require directives. /// /// @require directives indicate that a script uses functionality provided by a specified.net /// package in Jist marked with the JavascriptProvides attributre. If Jist is run without that /// package support, the script will not run. /// </summary> protected void PreprocessRequires(ref JistScript script) { if (script == null || string.IsNullOrEmpty(script.Script) == true || PreprocessorDirectives.requiresRegex.IsMatch(script.Script) == false) { return; } foreach (Match match in PreprocessorDirectives.requiresRegex.Matches(script.Script)) { string[] packages = match.Groups[2].Value.Split(','); foreach (string package in packages) { string trimmedPackage = package.Trim().Replace("\"", ""); if (string.IsNullOrEmpty(trimmedPackage) == true) { return; } script.PackageRequirements.Add(trimmedPackage); script.Script = script.Script.Replace(match.Value, string.Format("/** #pragma require \"{0}\" - DO NOT CHANGE THIS LINE **/\r\n", trimmedPackage)); } } }
/// <summary> /// Removes comments from a scripts content. /// </summary> protected void PreprocessComments(ref JistScript script) { if (script == null || string.IsNullOrEmpty(script.Script) == true) { return; } PreprocessorDirectives.multilineCommentRegex.Replace(script.Script, blankEvaluator); PreprocessorDirectives.singleLineCommentRegex.Replace(script.Script, blankEvaluator); }
public void PreprocessScript(JistScript script) { if (script == null || string.IsNullOrEmpty(script.Script) == true) { return; } PreprocessComments(ref script); PreprocessRequires(ref script); PreprocessImports(ref script); PreprocessInlines(ref script); }
protected void PreprocessInlines(ref JistScript script) { //@inline: inline imports script content into another script. if (PreprocessorDirectives.inlineRegex.IsMatch(script.Script)) { foreach (Match match in PreprocessorDirectives.inlineRegex.Matches(script.Script)) { string scriptLocation = match.Groups[1].Value; //prevent cyclic references if (!scriptLocation.Equals(script.FilePathOrUri)) { JistScript inlineContent = jistParent.LoadScript(scriptLocation, false); script.Script = script.Script.Replace(match.Value, ""); script.Script = script.Script.Insert(match.Index, string.Format("/** #pragma inline \"{0}\" **/\r\n{1}", scriptLocation, inlineContent.Script)); } } } }
protected void PreprocessImports(ref JistScript script) { //@import: tells the preprocessor to import the script into the engine, and load it. if (PreprocessorDirectives.importRegex.IsMatch(script.Script)) { foreach (Match match in PreprocessorDirectives.importRegex.Matches(script.Script)) { string scriptLocation = match.Groups[1].Value; //prevent cyclic references if (!scriptLocation.Equals(script.FilePathOrUri)) { jistParent.LoadScript(scriptLocation); string importedValue = string.Format("/** #pragma import \"{0}\" - Imported by engine - DO NOT CHANGE THIS LINE **/", scriptLocation); script.Script = script.Script.Replace(match.Value, importedValue); } } } }
/// <summary> /// Executes a script, and returns it's completion value. /// </summary> public JsValue ExecuteScript(JistScript script) { if (script == null || string.IsNullOrEmpty(script.Script) == true) { return JsValue.Undefined; } try { return jsEngine.Execute(script.Script).GetCompletionValue(); } catch (Exception ex) { ScriptLog.ErrorFormat(script.FilePathOrUri, "Execution error: " + ex.Message); return JsValue.Undefined; } }
/// <summary> /// Loads a script from file into a reference-counted object, and inserts it into /// the script container. /// /// Scripts are /not/ executed by the javascript engine at this point. /// </summary> public JistScript LoadScript(string ScriptPath, bool IncreaseRefCount = true) { JistScript content; /* * if this script has already been called for, return the called object * with an incremented ref count */ if (scriptContainer.Scripts.Count(i => i.FilePathOrUri.Equals(ScriptPath, StringComparison.InvariantCultureIgnoreCase)) > 0) { content = scriptContainer.Scripts.FirstOrDefault(i => i.FilePathOrUri.Equals(ScriptPath, StringComparison.InvariantCultureIgnoreCase)); if (IncreaseRefCount) { content.ReferenceCount++; } return null; } content = new JistScript(); content.FilePathOrUri = ScriptPath; content.ReferenceCount = 1; try { content.Script = File.ReadAllText(Path.Combine(scriptsDir, content.FilePathOrUri)); } catch (Exception ex) { ScriptLog.ErrorFormat("engine", "Cannot load {0}: {1}", ScriptPath, ex.Message); return null; } /* * Script must be added to the content list before preprocessing * this is to prevent cyclic references between @imports, used as an include guard */ scriptContainer.PreprocessScript(content); scriptContainer.Scripts.Add(content); return content; }