/// The extension name, this can be a comma separated list of extensions if this class supports more than one Projection RegisterExtension As %Projection.StudioDocument(DocumentDescription = "CachéJavaScript Routine", DocumentExtension = "cjs", DocumentIcon = 1, DocumentType = "JS");
ClassMethod ListExecute (ByRef qHandle As% Binary, Directory As% String, Flat As% Boolean, System As% Boolean) As% Status
{
Set qHandle = $ listbuild ( Directory , Flat , System , "" )
Quit $$$ OK
}
ClassMethod ListFetch (ByRef qHandle As% Binary, ByRef Row As% List, ByRef AtEnd As% Integer = 0) As% Status [PlaceAfter = ListExecute]
{
Set Row = "" , AtEnd = 0
If qHandle = "" Set AtEnd = 1 Quit $$$ OK
If $ list ( qHandle ) '= "" || ( $ list ( qHandle , 4) = 1) Set AtEnd = 1 Quit $$$ OK
set AtEnd = 1
Set rtnName = $ listget ( qHandle , 5)
For {
Set rtnName = $ order (^ rCJS ( rtnName )) Quit : rtnName = ""
continue : $ get (^ rCJS ( rtnName , "LANG" )) '= "CJS"
set timeStamp = $ zdatetime ( $ get (^ rCJS ( rtnName , 0)), 3)
set size = + $ get (^ rCJS ( rtnName , 0, "SIZE" ))
Set Row = $ listbuild ( rtnName _ ".cjs" , timeStamp , size , "" )
set AtEnd = 0
set $ list ( qHandle , 5) = rtnName
Quit
}
Quit $$$ OK
}
/// Return 1 if the routine is 'name' exists and 0 if it does not.
ClassMethod Exists (name As% String) As% Boolean
{
Set rtnName = $ piece ( name , "." , 1, $ length ( name , "." ) -1)
Set rtnNameExt = $ piece ( name , "." , $ Length ( name , "." ))
Quit $ data (^ rCJS ( rtnName )) && ( $ get (^ rCJS ( rtnName , "LANG" )) = $ zconvert ( rtnNameExt , "U" ))
}
/// Return the timestamp of the routine 'name' in% TimeStamp format. This is used to determine if the routine has
/// been updated on the server. So the format should be $ zdatetime ($ horolog, 3),
/// or "" if the routine does not exist.
ClassMethod TimeStamp (name As% String) As% TimeStamp
{
Set rtnName = $ piece ( name , "." , 1, $ length ( name , "." ) -1)
Set timeStamp = $ zdatetime ( $ get (^ rCJS ( rtnName , 0)), 3)
Quit timeStamp
}
/// Load the routine into the stream code
Method Load () As% Status
{
set source = .. Code
do source . Clear ()
set pCodeGN = $ name (^ rCJS (.. ShortName , 0))
for pLine = 1: 1: $ get (@ pCodeGN @ (0), 0) {
do source . WriteLine (@ pCodeGN @ ( pLine ))
}
do source . Rewind ()
Quit $$$ OK
}
/// Save the routine stored in Code
Method Save () As% Status
{
set pCodeGN = $ name (^ rCJS (.. ShortName , 0))
kill @ pCodeGN
set @ pCodeGN = $ ztimestamp
Set .. Code . LineTerminator = $ char (13,10)
set source = .. Code
do source . Rewind ()
WHILE '( source . AtEnd ) {
set pCodeLine = source . ReadLine ()
set @ pCodeGN @ ( $ increment (@ pCodeGN @ (0)) = pCodeLine
}
set @ pCodeGN @ ( "SIZE" ) = .. Code . Size
Quit $$$ OK
}
/// CompileDocument is when compiled
/// It has already been called the control hooks at this point.
Method CompileDocument (ByRef qstruct As% String) As% Status
{
Write !, “Compile:„ , .. Name
Set compiledCode = ## class ( % Routine ). % OpenId (.. ShortName _ “.INT" )
Set compiledCode . Generated = 1
do compiledCode . Clear ()
do compiledCode . WriteLine ( "; generated at" _ $ zdatetime ( $ ztimestamp , 3))
do .. GenerateIntCode ( compiledCode )
do compiledCode . % Save ()
do compiledCode . Compile ()
Quit $$$ OK
}
Method GenerateIntCode (aCode) [Internal]
{
set varMatcher = ## class ( % Regex.Matcher ). % New ( "[\ t] * (var [\ t] +)? (\ W [\ w \ d] *) [\ t] * (\ = [\ t] * (. *))?" )
set printlnMatcher = ## class ( % Regex.Matcher ). % New ( "[\ t] * (?: console \ .log | println) \ (([^ \)] +) \)?" )
set readMatcher = ## class ( % Regex.Matcher ). % New ( "[\ t] * read \ ((. *) \, (. *) \)" )
set source = .. Code
do source . Rewind ()
while ' source . AtEnd {
set tLine = source . ReadLine ()
set pos = 1
while $ locate ( tLine , "(([^ \ '\" "\; \ r \ n] | [\' \" "] [^ \ '\" "] * [\' \" ")) +) " , pos , pos , tCode ) {
set tPos = 1
if $ zstrip ( tCode , "* W" ) = "" {
do aCode . WriteLine ( tCode )
continue
}
if varMatcher . Match ( tCode ) {
set varName = varMatcher . Group (2)
if varMatcher . Group (1) '= "" {
do aCode . WriteLine ( $ char (9) _ «new„ _ varName )
}
if varMatcher . Group (3) '= “” {
set expr = varMatcher . Group (4)
set expr = .. Expression ( expr )
do : expr '= "" aCode . WriteLine ( $ char (9) _ “set„ _ varName _ “=„ _ expr )
}
continue
} elseif printlnMatcher . Match ( tCode ) {
set expr = printlnMatcher . Group (1)
set expr = .. Expression ( expr )
do : expr '= "" aCode . WriteLine ( $ char (9) _ “Write„ _ expr _ “,!” )
} elseif readMatcher . Match ( tCode ) {
set expr = readMatcher . Group (1)
set expr = .. Expression ( expr )
set var = readMatcher . Group (2)
do : expr '= "" aCode . WriteLine ( $ char (9) _ "read„ _ expr _ “," _ var _ ",!" )
}
}
}
}
ClassMethod Expression (tExpr) As% String
{
set matchers ( $ increment ( matchers ), "matcher" ) = "(? sm) ([^ \ '\" "] *) \ + [\ t] * (?: \" "([^ \" "] *) \ "" | \ '([^ \'] *) \ ') ([^ \' \ ""] *) "
set matchers ( matchers , "replacement" ) = "$ 1 _" "$ 2 $ 3" "$ 4"
set matchers ( $ increment ( matchers ), "matcher" ) = "(? sm) ([^ \ '\" "] *) (?: \" "([^ \" "] *) \" "| \ '([^ \'] *) \ ') [\ t] * \ + ([^ \' \ ""] *) "
set matchers ( matchers , "replacement" ) = "$ 1" "$ 2 $ 3" "_ $ 4"
set matchers ( $ increment ( matchers ), "matcher" ) = "(? sm) ([^ \ '\" "] *) (?: \" "([^ \" "] *) \" "| \ '([^ \'] *) \ ') ([^ \' \ ""] *) "
set matchers ( matchers , "replacement" ) = "$ 1" "$ 2 $ 3" "$ 4"
set tResult = tExpr
for i = 1: 1: matchers {
set matcher = ## class ( % Regex.Matcher ). % New ( matchers ( i , "matcher" ))
set replacement = $ get ( matchers ( i , "replacement" ))
set matcher . Text = tResult
set tResult = matcher . ReplaceAll ( replacement )
}
quit tResult
}
/// Return other document types.
/// Passed a comma
/// or "" if it is not related to anything. Note
/// for example if your test.XXX your document creates a test.INT
/// with 'test.INT' so you can return 'test.XXX' to complete the cycle.
ClassMethod GetOther (Name As% String) As% String
{
Set rtnName = $ piece ( Name , "." , 1, $ length ( Name , "." ) -1) _ ".INT"
Quit : ## class ( % Routine ). % ExistsId ( rtnName ) rtnName
Quit ""
}
/// Delete the routine 'name' which includes the routine extension
ClassMethod Delete (name As% String) As% Status
{
Set rtnName = $ piece ( name , "." , 1, $ length ( name , "." ) -1)
Kill ^ rCJS ( rtnName )
Quit $$$ OK
}
/// Lock the current routine;
/// If it fails then return a status code of the error, otherise return $$$ OK
Method Lock (flags As% String) As% Status
{
Lock + ^ rCJS (.. Name ): 0 Else Quit $$$ ERROR ( $$$ CanNotLockRoutine , .. Name )
Quit $$$ OK
}
/// Unlock the current routine
Method Unlock (flags As% String) As% Status
{
Lock - ^ rCJS (.. Name )
Quit $$$ OK
}
/// Studio Template: <br> /// Create a new Cache JavaScript Routine. Class% CJS.RoutineWizard Extends% ZEN.Template.studioTemplate [StorageStrategy = ""] { Parameter TEMPLATENAME = "Cache JavaScript"; Parameter TEMPLATETITLE = "Cache JavaScript"; Parameter TEMPLATEDESCRIPTION = "Create a new Cache JavaScript routine."; Parameter TEMPLATETYPE = "CJS"; /// What type of template. Parameter TEMPLATEMODE = "new"; /// If this is a TEMPLATEMODE = "new" then this is /// in Studio this template is dispayed on. If none specified then /// it displays on the 'Custom' tab. Parameter TEMPLATEGROUP As STRING; /// This XML block is the pane of this Studio Template. XData templateBody [XMLNamespace = "http://www.intersystems.com/zen"] { <pane id = "body"> <vgroup labelPosition = "left" cellStyle = "padding: 2px; padding-left: 5px; padding-right: 5px;"> <html id = "desc" OnDrawContent = "% GetDescHTML" /> <text label = "Routine Name:" id = "ctrlRoutineName" name = "RoutineName" size = "40" required = "true" labelClass = "zenRequired" title = "Cache JavaScript Routine name" onchange = "zenPage.updateState ();" /> </ vgroup> </ pane> } /// Provide contents of description component. Method% GetDescHTML (pSeed As% String) As% Status { Quit $$$ OK } /// This is called when the template is first; /// This provides a chance to set focus etc. ClientMethod onstartHandler () [Language = javascript] { // give focus to name var ctrl = zenPage.getComponentById ('ctrlRoutineName'); if (ctrl) { ctrl.focus (); ctrl.select (); } } /// Validation handler for form built-into template. ClientMethod formValidationHandler () [Language = javascript] { var rtnName = zenPage.getComponentById ('ctrlRoutineName'). getValue (); if ('' == rtnName) { return false; } return true; } /// This method is when the template is complete. Any /// output to the Studio device. Method% OnTemplateAction () As% Status { Set tRoutineName = ..% GetValueByName ("RoutineName") Set% session.Data ("Template", "NAME") = tRoutineName _ ". CJS" Write "//" _tRoutineName ,! Quit $$$ OK } }
// hello console.log('Hello World!'); var name=''; read('What is your name? ', name); println('Hello ' + name + '!');
; generated at 2014-05-18 20:06:36
Write "Hello World!" ,!
new name
set name = ""
read "What is your name? „ , Name,!
Write “Hello„ _ name _ “!” ,!
USER> d ^ hello Hello World! What is your name? daimor Hello daimor!
Source: https://habr.com/ru/post/222563/
All Articles