|
Class: JavaScriptParser
Object
|
+--Scanner
|
+--JavaScriptScanner
|
+--JavaScriptParser
|
+--JavaScriptCompiler
|
+--JavaScriptCompletionParser
|
+--JavaScriptSyntaxHighlighter
- Package:
- stx:libjavascript
- Category:
- Languages-JavaScript-Compiling & Parsing
- Version:
- rev:
1.395
date: 2024/02/09 12:34:09
- user: stefan
- file: JavaScriptParser.st directory: libjavascript
- module: stx stc-classLibrary: libjavascript
reads JavaScript-like syntax, builds up an AST similar to the ST-AST.
Used for expecco, so be careful when changing.
copyrightCOPYRIGHT (c) 1998 by eXept Software AG
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
example1a little script as it may be in a scriptfile
example2|env val source|
source :=
'
STXScriptingServer.errorDebugging(true);
Stdout.showCR(''hello'');
var filename;
var verdict, result;
filename = ''~/SuiteA.ets'';
verdict = Expecco::ExpeccoAPI.executeTestsFromFile_filteredByName_filteredByTag_testIDList_verboseInfoHandler_parameterFile_reporter(
filename,
null, /* namefilter */
null, /* tagFilter */
null, /* id-list */
null, /* info handler */
null, /* parameter file */
(function (rslt) { result = rslt; }) /* reporter */
);
if (verdict.isSuccess) {
alert(''ok'');
} else {
alert(''not ok'');
}
'.
env := STXScriptingEnvironment new.
val :=
JavaScriptParser new
source:source readStream;
evaluateDeclarationsFor:env.
self assert:(env _localVariables at:#'filename') value = '~/SuiteA.ets'.
self assert:(env _localVariables at:#'verdict') value isSuccess.
(env _localVariables at:#'result') value inspect.
expression_examplesTestCase assert:(JavaScriptParser evaluate:'3*3') = 9
TestCase assert:(JavaScriptParser evaluate:'(8+7) % 13') = 2
TestCase assert:(JavaScriptParser evaluate:'(5*4) % 13') = 7
TestCase assert:(JavaScriptParser evaluate:'Math.floor(7/2)') = 3
(JavaScriptParser evaluate:'Stdout.showCR(''hello'')')
TestCase assert:(JavaScriptParser evaluate:'Math.gcd(5,64)') = 1
(JavaScriptParser evaluate:'var x = { foo: ''hello'', bar:''world'' }; return x;' ) inspect
other_examples<<END
[exBegin]
|env|
env := JavaScriptEnvironment new.
env _defineVariable:#UIMap value:(Expecco::SeleniumUIMap).
JavaScriptParser
evaluateDeclarationsFrom:'C:\Temp\selenium\ui_map_expecconet.js' asFilename readStream
for:env.
self halt.
[exEnd]
[exBegin]
|env rslt1 rslt2|
env := JavaScriptEnvironment new.
env _defineVariable:#foo value:'abc'.
env _defineVariable:#bar value:'def'.
rslt1 := JavaScriptParser
evaluate:' "this is foo: $(foo) and this is bar: $(bar)" '
in:env.
rslt2 := JavaScriptParser
evaluate:' `this is foo: $(foo) and this is bar: $(bar)` '
in:env.
self halt.
[exEnd]
[exBegin]
|dummyReceiver code mthd|
code := ('C:\Temp\selenium\ui_map_expecconet.js' asFilename contentsAsString).
Class nameSpaceQuerySignal answer:ExpeccoDummyNameSpaceForSeleniumScripts
do:[
mthd := JavaScriptCompiler
compile: ('doIt() { ',code ,' return(thisContext()); };')
forClass:nil
inCategory:nil
notifying:nil
install:false
].
dummyReceiver := JavaScriptObject new.
mthd valueWithReceiver:dummyReceiver arguments:#()
[exEnd]
END>>"
configuration
-
forInAllowed
-
do we allow for(var in expr) {...} ?
-
forOfAllowed
-
do we allow for(var of expr) {...} ?
evaluation
-
evaluate: aStringOrStream
-
evaluate a javaScript expression.
A new environment is created, where variables are defined.
Usage example(s):
self evaluate:'1 + 2 * 3 + 4'
|
Usage example(s):
self evaluate:'
if (1 > 2) {
Transcript.showCR(1);
} else {
Transcript.showCR(2);
}
'
|
Usage example(s):
self evaluate:'
if (1 > 2) {
Transcript.foo(1,2,3,4,5,6,7,8,9,10);
} else {
Transcript.bar(1,2,3,4,5,6,7,8,9,10);
}
'
|
Usage example(s):
self evaluate:'
if (1 > 2) {
Transcript.show(hello);
} else {
Transcript.show(world);
}
Transcript.cr;
'
|
-
evaluate: aStringOrStream in: anEnvironment
-
like #evaluate, but take anEnvironment for variable/function declarations.
New vars/functions will be added to that one; lookup for vars/methods
is done there.
If a nil environment is given, a new one will be created for the
evaluation and discarded afterwards.
-
evaluate: aString in: anEnvironment receiver: someObject notifying: requestor logged: logged ifFail: failBlock
-
-
evaluate: aStringOrStream in: anEnvironment receiver: anObject notifying: requestor logged: logged ifFail: failBlock compile: compile
-
return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.
-
evaluate: aStringOrStream receiver: receiver in: anEnvironment
-
like #evaluate, but take anEnvironment for variable/function declarations.
New vars/functions will be added to that one; lookup for vars/methods
is done there.
If a nil environment is given, a new one will be created for the
evaluation and discarded afterwards.
-
evaluateDeclarationsFrom: aStringOrStream for: anEnvironment
-
-
evaluateFrom: aStringOrStream ifFail: exceptionValue
-
evaluate a javaScript expression.
A new environment is created, where variables are defined.
initialization
-
initialize
-
ActionArray := nil
-
postAutoload
-
(comment from inherited method)
postAutoload is sent to a class after it has been autoloaded.
This gives it a chance to arrange for automatic unloading to be done
after a while ...
This is NOT sent to statically compiled in or explicitely filedIn
classes.
The default action here is to do nothing.
instance creation
-
for: aStringOrStream in: aClass
-
return a new parser, reading code for aClass from aStringOrStream
parsing
-
methodCommentFromSource: aStringOrStream
-
here, the methodComment is usually outside of the method's code,
so comments before the function are included in the search, but after it are not.
Usage example(s):
JavaScriptParser methodCommentFromSource:'
// foo bar baz
function x() {
halt();
}
// bla bla
'
|
-
methodCommentsFromSource: aStringOrStream
-
returns all comments found in aStringOrStream.
Here, the methodComment is usually outside of the method's code,
so comments before the function are included, but after it are not.
Usage example(s):
JavaScriptParser methodCommentsFromSource:'
// foo bar baz
function x() {
halt();
}
// bla bla
'
|
-
parse: aStringOrStream class: aClass
-
parse whatever is the unit of compilation in ST/X's browser
Usage example(s):
self parse:'function foo(a, b, c) {}' class:nil
|
Usage example(s):
self parse:'function foo(a, b, c) { return a+b; }' class:nil
|
-
parseClassDefinition: aStringOrStream
-
-
parseClassFile: aStringOrStream
-
aStringOrStream
-
parseExpression: aStringOrStream
-
self
parseExpression:'1 + 2 * 3 + 4'
Usage example(s):
self
parseExpression:'1.1 + 2.2'
|
-
parseExpression: aStringOrStream setup: setupBlock onError: aBlock
-
self
parseExpression:'1 + 2 * 3 + 4'
Usage example(s):
self
parseExpression:'1.1 + 2.2'
|
-
parseFunction: aStringOrStream
-
self
parseFunction:'function foo(a, b, c) {}'
Usage example(s):
self
parseFunction:'function foo(a, b, c) { return a+b; }'
|
-
parseFunction: aStringOrStream in: aClass
-
self
parseFunction:'function foo(a, b, c) {}'
Usage example(s):
self
parseFunction:'function foo(a, b, c) { return a+b; }'
|
-
parseMethod: aStringOrStream
-
parse a method in a given class. Return a parser (instance of myself).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
-
parseMethod: aStringOrStream in: aClass
-
parse a method in a given class. Return a parser (instance of myself).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
-
parseMethod: aStringOrStream in: aClass ignoreErrors: ignoreErrors ignoreWarnings: ignoreWarnings
-
parse a method in a given class.
Return a parser (instance of myself).
The parser can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
-
parseMethodArgAndVarSpecificationSilent: aStringOrStream
-
-
parseMethodSilent: aString
-
parse a method.
Return a parser (if ok), nil (empty) or #Error (syntax).
The parser can be queried for selector, receiver, args, locals,
used selectors etc.
Like #parseMethod:, but warning/error messages are suppressed.
-
parseMethodSilent: aStringOrStream in: aClass
-
-
parseMethodSpecificationSilent: aStringOrStream
-
-
parseStatementBlockBody: aStringOrStream
-
self
parseStatementBlockBody:'1+2'
Usage example(s):
self
parseStatementBlockBody:'var a; a'
|
Usage example(s):
Class nameSpaceQuerySignal
answer:JavaScriptEnvironment
do:[
self
parseStatementBlockBody:'Math.PI'
]
|
-
xx_parseMethodSpecification: aStringOrStream in: aClass ignoreErrors: ignoreErrors ignoreWarnings: ignoreWarnings
-
queries
-
parseNodeVisitorClass
-
selector translation
-
commonTranslatedSelectorFor: jsSelector
-
common translation (both JS-in-ST and JS-in-HTML).
Given a javascript operator or function name,
translate it into a corresponding smalltalk selector for a message send
Usage example(s):
self commonTranslatedSelectorFor:#'%'
self commonTranslatedSelectorFor:#'split'
self commonTranslatedSelectorFor:#'fooBar'
|
-
reverseCommonTranslatedSelectorFor: smalltalkSelector
-
reverse translation.
Given a smalltalk selector, return a corresponding JavaScript
operator or function name.
Used by the document generator only
-
reverseTranslatedJavaScriptSelectorFor: smalltalkSelector
-
return the javaScript selector for a given smalltalk selector.
Given a javascript operator or function name,
translate it into a corresponding smalltalk selector.
THIS IS ONLY TO BE USED FOR DOCUMENTATION PURPOSES
Usage example(s):
self reverseTranslatedJavaScriptSelectorFor:#show:
self reverseTranslatedJavaScriptSelectorFor:#at:
self reverseTranslatedJavaScriptSelectorFor:#at:put:
self reverseTranslatedJavaScriptSelectorFor:#+
self reverseTranslatedJavaScriptSelectorFor:#-
|
-
selectorForFunctionName: jsName numArgs: nargs
-
given a javaScript function name,
return an appropriate valid smalltalk selector.
This is used when methods are compiled
Usage example(s):
self selectorForFunctionName:'foo' numArgs:0
self selectorForFunctionName:'foo' numArgs:1
self selectorForFunctionName:'foo' numArgs:2
self selectorForFunctionName:'foo' numArgs:3
|
-
selectorMapping
-
this table defines the selector translation common for both JS-in-ST and JS-in-HTML.
temporary hacks for DWIM
-
parseMethod: aStringOrStream setup: setupBlock onError: onErrorBlock
-
nodesSoFar
accessing
-
currentEnvironment
-
-
currentNameSpace: aNameSpace
-
-
currentNamespace: aNameSpace
-
** This is an obsolete interface - do not use it (it may vanish in future versions) **
-
interactiveMode: something
-
support for stx-scripting service
-
methodCategory
-
-
methodCategory: something
-
-
moreSharedPools: aCollection
-
-
selector
-
-
smalltalkSelector
-
-
targetClass
-
-
targetClass: aClass
-
-
translateCallsToSelfSends: something
-
-
tree
-
return the value of the instance variable 'tree' (automatically generated)
-
tree: something
-
set the value of the instance variable 'tree' (automatically generated)
debugging
-
inspector2TabParseTreeInspector
-
dummy-syntax detection
-
markArgumentIdentifierFrom: pos1 to: pos2
-
intentionally left blank here
-
markFieldNameFrom: pos to: endPos
-
intentionally left blank here
-
markFunctionNameFrom: pos1 to: pos2
-
intentionally left blank here
-
markGlobalIdentifierFrom: pos1 to: pos2
-
intentionally left blank here
-
markIdentifierFrom: pos1 to: pos2
-
intentionally left blank here
-
markKeyword: kw from: pos1 to: pos2
-
intentionally left blank here
-
markKeywordToken
-
intentionally left blank here
-
markLocalIdentifierFrom: pos1 to: pos2
-
intentionally left blank here
-
markSelector: id from: pos1 to: pos2 receiverNode: aReceiverNodeOrNil numArgs: numArgs
-
intentionally left blank here
-
markSelfFrom: pos1 to: pos2
-
intentionally left blank here
-
markSuperFrom: pos1 to: pos2
-
intentionally left blank here
-
markVariable: v
-
intentionally left blank here
-
markVariable: v from: pos to: endPos
-
intentionally left blank here
error handling
-
parseError: aMessage position: position to: endPos
-
ParseError raiseRequestErrorString:aMessage
-
undefError: varName
-
self parseError:'unknown global: ' , varName.
-
warning: msg
-
^ super warning:msg
evaluation
-
evaluate: aString in: anEnvironment receiver: someObject notifying: requestor logged: logged ifFail: failBlock
-
true -- assuming that subclasses can compile
-
evaluate: aStringOrStream in: anEnvironment receiver: anObject notifying: requestor logged: logged ifFail: failBlock compile: compile
-
return the result of evaluating aStringOrStream, errors are reported to requestor.
Allow access to anObject as self and to its instVars (used in the inspector).
If logged is true, an entry is added to the change-file. If the failBlock argument
is non-nil, it is evaluated if an error occurs.
Finally, compile specifies if the string should be compiled down to
bytecode or instead be interpreted from the parseTree.
The first should be done for doIts etc, where a readable walkback is
required.
The latter is better done for constants, styleSheet and resource
reading and simple sends, where the overhead of compilation is bigger
than the interpretation overhead.
-
evaluateDeclarationFor: anEnvironment
-
this is used with the scripting interpreter, where an existing environment
is used and manipulated (i.e. declared variables are persistent across evaluations).
Reads a single decl; for function decls, declare them;
for statements & expressions, evaluate them.
-
evaluateDeclarationsFor: anEnvironment
-
read; for function decls, declare them; for statements & expressions,
evaluate them.
Returns the value of the last expression
helpers
-
commonTranslatedSelectorFor: jsSelector
-
-
currentNameSpace
-
-
expect: expected
-
-
expectKeyword: expected
-
-
findNameSpaceWith: aVariableName
-
"/ private names have already been searched for.
-
ifRequiredTranslateSelectorIn: aNode
-
we are compiling a javaScript-script in a browser.
-
isOpAssignSymbol: token
-
-
selectorForFunctionName: arg1 numArgs: arg2
-
-
topEnvironment
-
-
translatedJSSelectorFor: selector numArgs: numArgs
-
translate selectors as req'd for HTML-scripts.
All selectors get a js_ prepended, to avoid conflicts with corresponding
smalltalk selectors.
This is especially req'd, as at:/at:put: in JS are 0-based,
while being 1-based in ST.
Thus, the translation allows for indexOf: to remain unchanged, and js_indexOf: returns a 0-based index.
-
translatedSmalltalkSelectorFor: jsSelector numArgs: numArgs
-
translate javaScript selectors as req'd for compiled JTalk.
Given a javascript operator or function name,
translate it into a corresponding smalltalk selector for a message send
initialization
-
environment: anEnvironment
-
-
foldConstants: aBoolean
-
-
initialize
-
(comment from inherited method)
initialize the scanner
-
isDoIt
-
-
isDoIt: aBoolean
-
-
parseForCode
-
-
setAllClassVarNames: aCollectionOfNameStrings
-
set the collection of classvar names.
This is provided for subclasses (Node, Groovy)
-
setAllInstVarNames: aCollectionOfNameStrings
-
set the collection of instvar names.
This is provided for subclasses (Node, Groovy)
-
setClassToCompileFor: aClass
-
set the class to be used for parsing/evaluating
-
setSelf: anObject
-
(classToCompileFor ~~ PrevClass) ifTrue:[
-
smalltalkCompatibilityMode
-
in smalltalk mode, array indexing is 1-based,
and conditions must be booleans.
in non-smalltalk (i.e. javaScript) mode, indexing is 0 based
and conditions can also be integers (treating 0 as false).
The default is true (and MUST remain so for expecco)
-
smalltalkCompatibilityMode: aBoolean
-
in smalltalk mode, array indexing is 1-based,
and conditions must be booleans.
in non-smalltalk (i.e. javaScript) mode, indexing is 0 based
and conditions can also be integers (treating 0 as false).
The default is true (and MUST remain so for expecco)
-
untranslatedJavaScriptSelectors1
-
-
untranslatedJavaScriptSelectors1: anArray
-
Modified (format): / 28-02-2022 / 10:01:47 / Stefan_Vogel
-
untranslatedJavaScriptSelectors2
-
-
untranslatedJavaScriptSelectors2: anArray
-
Modified (format): / 28-02-2022 / 10:02:23 / Stefan_Vogel
parsing
-
argList
-
arg | argList , arg
-
classDefinition
-
public class <name> extends <superName> {
<varDecls>
}
-
classNameIdentifier
-
-
constDeclaration
-
'const' name [ '=' constExpression ]';'
-
constDeclarationFor: anEnvironment
-
[ 'static' ] 'const' name ['=' initExpr] ';'
-
constOrVarDeclarationFor: anEnvironment isConst: isConstIn
-
[ 'static' ] ('const'|'var') name ['=' initExpr] ';'
| 'let' name ['=' initExpr] ';'
-
declareConstant: varName inEnvironment: anEnvironment
-
-
declareStaticConstant: varName
-
name (not eaten)
-
declareStaticVariable: varName
-
name (not eaten)
-
declareStaticVariable: varName isConstant: isConstant
-
name (not eaten)
-
declareVariable: varName inEnvironment: anEnvironment
-
-
declareVariable: varName inEnvironment: anEnvironment isConstant: isConstant
-
caveat: isConstant is currently ignored
-
fileSource
-
process a complete file's source (multiple declarations)
-
function
-
function(args) stats ;
-
function: readOverClosingBrace
-
function(args) stats ;
-
functionBodyFor: functionNameOrNil asInnerFunction: asInnerFunction
-
(args) stats ;
-
functionBodyFor: functionNameOrNil asInnerFunction: asInnerFunction withStatements: withStatements
-
(args) stats ;
-
functionName
-
function name(args) stats ;
| function className.name(args) stats ;
| function className.class.name(args) stats ;
-
functionOrStaticFunction: readFinalBrace
-
[static] function(args) stats ;
-
functionOrStaticFunctionOrClass: readFinalBrace
-
[static] function(args) stats ;
[static] class ...
-
lambdaFunctionBodyWithArguments: argList
-
{ stats }
| expr
-
needSemi
-
;
possibly omitted
-
parseClass: isStatic readFinalBrace: readOverClosingBrace
-
class (args) stats ;
Usage example(s):
self parseClass:'class Foo {}'
|
-
parseDeclarationsFor: anEnvironment
-
read; for function decls, declare them; for statements & expressions,
parse (but do not evaluate) them.
-
parseExpressionWithSelf: anObject notifying: someOne ignoreErrors: ignoreErrors ignoreWarnings: ignoreWarnings inNameSpace: aNameSpaceOrNil
-
parse aString as an expression with self set to anObject;
Return the parseTree (if ok), nil (for an empty string
or comment only ) or #Error (syntactic error).
Errors and warnings are forwarded to someOne (usually some
codeView) which can highlight it and show a popup box,
iff ignoreErrors/ignoreWarnings is true respectively.
-
parseMethod
-
parse the next function (aka method) from my current source stream
-
parseMethod: theCode in: aClass ignoreErrors: ignoreErrorsArg ignoreWarnings: ignoreWarningsArg
-
parse a function (aka method) from a different code stream.
After parsing, I can be queried for selector, receiver, args, locals,
used selectors, modified instvars, referenced classvars etc.
-
parseTopLevelElement
-
these are consts, vars, functions.
Can be redefined to eg. parse imports
-
rememberAssignmentTo: var
-
type == #PoolVariable ifTrue:[
-
rememberReadOf: var
-
type == #PoolVariable ifTrue:[
-
varDeclaration
-
[ 'static' ] 'var' name ['=' initExpr] ';'
[ 'static' ] 'const' name ['=' initExpr] ';'
| 'let' name ['=' initExpr] ';'
-
varDeclarationFor: anEnvironment
-
[ 'static' ] 'var' name ['=' initExpr] ';'
[ 'static' ] 'const' name ['=' initExpr] ';'
| 'let' name ['=' initExpr] ';'
parsing-expressions
-
addExpression
-
addExpr -> mulExpr addOp mulExpr
-
arrayConstant
-
arrayConstant -> Integer-constant
| Float-constant
| String-constant
| true
| false
| null
| arrayLiteral
| objectLiteral
-
arrayIndexing: expr
-
arrayIndexing -> [...]
-
arrayIndexingExpression: recIn
-
an initial 'recIn.' has already been scanned;
arrayIndexingExpression -> variableOrFunctionExpression
| variableOrFunctionExpression[ indexExpr ]
-
arrayIndexingExpressionList: exprIn
-
arrayIndexingExpressionList ->
.identifier(...)
| [ array-expr ]
-
arrayLiteral
-
arrayLiteral -> [ nonCommaExpression { , nonCommaExpression } ] ']'
initial opening bracket has NOT been read.
-
awaitExpression
-
-
bitAndExpression
-
bitAndExpression -> equalityExpr & equalityExpr
-
bitOrExpression
-
bitOrExpression -> bitXorExpr | bitXorExpr
-
bitShiftExpression
-
conditionalExpr -> addExpr shiftOp addExpr
-
bitXorExpression
-
bitXorExpression -> bitAndExpr ^ bitAndExpr
-
booleanAndExpression
-
booleanAndExpression -> bitOrExpr && bitOrExpr
-
booleanOrExpression
-
booleanAndExpression -> bitOrExpr || bitOrExpr
-
commaExpression
-
commaExpression -> conditionalExpression [, commaExpression ]
-
compareExpr
-
compareExpr -> bitShiftExpr relOp bitShiftExpr
-
compoundExpression
-
-
conditionalExpression
-
conditionalExpr -> boolOrExpr ? boolOrExpr
-
constantExpression
-
-
equalityExpression
-
equalityExpression -> compareExpr relOp compareExpr
-
expression
-
expression -> commaExpression
-
expressionList
-
expression | expressionList , expression
-
functionCallExpression: recIn
-
functionCallExpression -> var
| var(argList)
-
mulExpression
-
mulExpr -> powerExpression mulOp powerExpression
-
newExpression
-
for now, we do not support full expressions here...
-
nonCommaExpression
-
-
objectLiteral
-
objectLiteral -> '{' [ slotName ':' literal { , slotName ':' literal } ] '}'
opening brace has already been read
-
objectLiteralOrDescructuringExpression
-
opening brace has already been read
objectLiteral -> '{' [ slotName ':' literal { , slotName ':' literal } ] '}'
desctruct -> '{' [ slotName , slotName , ... '}'
-
powerExpression
-
powerExpr -> unaryExpr ** unaryExpr
-
primaryExpression
-
primaryExpr ->
'(' expr ')'
| '(' id1,...idN ')' '=>' lambdaFunctionBody
| '(' ')' '=>' lambdaFunctionBody
| variable '=>' lambdaFunctionBody
| constant
| 'this'
| 'super'
| variable
| 'new' class
| 'new' funcOrClass '(' dim ')'
| 'function' '(' argList ')' '{' statements '}'
-
typeofExpression
-
-
unaryExpression
-
unaryExpr -> ! unaryExpression
| ~ unaryExpression
| - unaryExpression
| ++unaryExpression
| --unaryExpression
| primaryExpression
| primaryExpression--
| primaryExpression++
| typeof primaryExpression
| await expression
-
varDeclaringExpression
-
an expression inside a for loop;
slightly different, allowing an already declared varName to be (re)-defined
-
variable: idAlreadyScanned
-
-
variable: idAlreadyScanned ignoreErrors: ignoreErrors
-
if there is one in the current evaluationContext,
parsing-statements
-
breakStatement
-
breakStatement -> break ';'
-
catchPartFor: tryBlockNode
-
tryCatchStatement -> try {
...
statements
...
}
catch([Error] [exVar] ) {
...
statements
...
}
[ finally {
...
statements
...
}
Notice: try { ... } has already been parsed.
Either Error-name or exVar or both may be present in the catch
(but one of them at least)
-
continueStatement
-
continueStatement -> continue ';'
-
doWhileStatement
-
doWhileStatement -> do stat while (expression)
-
finallyPart
-
finallyPart -> finally {
...
statements
...
}
-
forStatement
-
forStatement -> for (initexpr ; condexpr ; increxpression) stat
| for (variable in array) stat
-
functionDefinition
-
ok without semi
-
ifStatement
-
ifStatement -> if (expression) stat [ else stat ]
-
returnStatement
-
returnStatement -> return [ expression ] ['from' outerFunctionName ] ';'
-
statement
-
statement -> expression ;
-
statementBlock
-
statementBlock -> { statList } | statement
-
statementBlock: readClosingBraceBoolean
-
statementBlock -> { statList } | statement
-
statementBlockBody
-
statementBlock -> [ var decl ] statList
-
statementBlockBodyFor: anEnvironment
-
statementBlock -> [ var decl ] statList
-
statementWithSemi: needSemi
-
statement ->
var varName ....
let varName ....
const varName ....
static var varName ....
function ....
ifStatement
whileStatement
doStatement
returnStatement
forStatement
switchStatement
breakStatement
continueStatement
tryStatement
throwStatement
{ statementBlock }
expression ;
-
statements
-
statement -> expression ;
-
switchStatement
-
switchStatement -> switch (expression) {
case constant-expression1:
...
stat
...
break ;
case constant-expression2:
...
default:
...
}
-
throwStatement
-
throwStatement -> throw expression ';'
-
tryStatement
-
tryStatement -> try {
...
statements
...
}
( catchPart | finallyPart ]
-
whileStatement
-
whileStatement -> while (expression) stat
private
-
addDoItTemporary: varName
-
-
doItTemporaries
-
-
functionCallNodeForReceiver: rec selector: id args: argList fold: fold
-
-
handleCategoryDirective: categoryString
-
callback from the scanner, whenever it encountered a category comment-directive
-
implicitFunctionCallNodeForReceiver: rec selector: id args: argList fold: fold
-
-
isKeywordUsedAsIdentifier: tokenType
-
-
isSyntaxHighlighter
-
-
nameSpaceSelectorFor: aSymbol
-
Caring for the current namespace, return the real selector used for a send.
-
realFunctionCallNodeForReceiver: rec args: argList fold: fold
-
block evaluation - generate a value-send
-
realFunctionCallNodeForReceiver: rec selector: id args: argList fold: fold
-
block evaluation - generate a value-send
-
saveParseAheadDo: aBlock
-
restore old scanner state
queries
-
isEmptyMethod
-
return true (after a parse) if this is an empty (documentation) method
-
methodArgs
-
-
methodVars
-
-
wasParsedForCode
-
a kludge for compatibility
queries-statistic
-
messagesPossiblySent
-
return a collection with possible message selectors (valid after parsing).
Includes things known or possibly used with #perform or in specs.
Not yet implemented here.
Usage example(s):
^ (messagesPossiblySent ? #()) collect:[:each | each asSymbol]
|
-
messagesSent
-
return a set with sent message selectors (valid after parsing).
Includes all sent messages (i.e. also sent super messages)
-
messagesSentToSelf
-
that is not true - for now, to make the browser happy
-
messagesSentToSuper
-
that is not true - for now, to make the browser happy
-
modifiedClassVars
-
-
modifiedGlobals
-
-
modifiedInstVars
-
-
usedClassVars
-
-
usedGlobals
-
-
usedInstVars
-
-
usedVars
-
-
usesSuper
-
return true if the parsed method uses super (valid after parsing)
statistic
-
rememberClassVarModified: name
-
-
rememberClassVarRead: name
-
-
rememberClassVarUsed: name
-
-
rememberGlobalModified: name
-
-
rememberGlobalRead: name
-
-
rememberGlobalUsed: name
-
-
rememberInstVarModified: name
-
-
rememberInstVarRead: name
-
-
rememberInstVarUsed: name
-
-
rememberLocalModified: name
-
modifiedLocalVars isNil ifTrue:[
-
rememberLocalRead: name
-
readLocalVars isNil ifTrue:[
-
rememberLocalUsed: name
-
usedLocalVars isNil ifTrue:[
-
rememberVariableUsed: name
-
syntax detection
-
postProcessTree: aParseTree forText: text
-
allows for additional checks to be done on the tree
(checking arguments to a call-node in expecco, for example)
temporary hacks for DWIM
-
nodeGenerationCallback: nodeGenerationHook
-
-
rememberNodes: aBoolean
-
enable node remembering.
In case of an error, this allows for the nodes which have been collected
so far to be fetched. Useful for code completion of incomplete (erroneous) code.
-
rememberTokens: aBoolean
-
enable token remembering.
In case of an error, this allows for the tokens which have been collected
so far to be fetched. Useful for code completion of incomplete (erroneous) code.
-
rememberedNodes
-
In case of an error, this allows for the nodes which have been collected
so far to be fetched. Useful for code completion of incomplete (erroneous) code.
-
rememberedTokens
-
In case of an error, this allows for the tokens which have been collected
so far to be fetched. Useful for code completion of incomplete (erroneous) code.
utilities
-
ensureBooleanExpression: expr
-
relops are guaranteed to return booleans...
AndExpressionNode
ArrayAccessNode
ArrayStoreNode
AwaitNode
BreakStatementNode
CommaExpression
ConditionalNode
ContinueStatementNode
DoWhileStatementNode
ForStatementNode
FunctionCallNode
IfStatementNode
ImplicitFunctionCallNode
IncDecNode
InnerJavaBlockNode
JavaScriptAssignmentNode
JavaScriptBinaryNode
JavaScriptMultiVariableNode
JavaScriptReturnNode
JavaScriptStatementNode
JavaScriptUnaryNode
NewNode
OrExpressionNode
PostIncDecNode
PreIncDecNode
StatementBlockNode
SwitchStatementNode
ThisNode
ThrowStatementNode
TryCatchStatementNode
TypeOfNode
WhileStatementNode
JavaScriptParser parseExpression:'3 != 4'
| JavaScriptParser parseExpression:'0b11 + 0b100'
(JavaScriptParser parseExpression:'3 + 4 * 5') evaluate
|
JavaScriptParser parseExpression:'(3 != 4) && (5 == 5)'
|
(JavaScriptParser parseExpression:'(3 == 4) || (5 == 5)') evaluate
|
JavaScriptParser parseExpression:'!(3 != 4)'
|
(JavaScriptParser parseExpression:'(3 != 4)') evaluate
|
(JavaScriptParser parseExpression:'!(3 != 4)') evaluate
|
#(
'1 + 2 * 3 + 4'
'1 * 2 * 3 * 4'
'1 + 2 / 3'
'10 / 3'
'11 & 3'
'0x8000'
'0377'
'3 == 3'
'3 != 3'
'3 == 4'
'3 != 4'
'3 > 3'
'3 >= 3'
'3 < 3'
'3 <= 3'
'3 > 4'
'3 >= 4'
'3 < 4'
'3 <= 4'
'4 > 3'
'4 >= 3'
'4 < 3'
'4 <= 3'
'0x8>>2'
'8 << 2'
'8 >>> 2'
) do:[:s |
Transcript
show:'''';
show:s;
show:'''';
show:' -> ';
showCR:(JavaScriptParser parseExpression:s) evaluate.
]
|
JavaScriptParser
parseFunction:'function foo(a, b, c) {}'
|
JavaScriptParser
parseFunction:'function foo(a, b, c) {
if (a > 1) {
return a;
} else {
return b;
}
}'
|
JavaScriptParser
parseFunction:'
function bar(a, b, c) {
var sum;
while (a > 1) {
sum += a;
a--;
}
return sum;
}'
|
JavaScriptParser
parseFunction:'
function bar(a, b, c) {
var sum;
var j;
if ( foo(a,b) ) {
for (j=0; j<=a.length; j++) {
if (c[j] <= c[j+1])
break;
}
}
return sum;
}'
|
JavaScriptParser
parseFunction:'
function bar(a, b, c) {
var sum;
if ( foo(a,b) ) {
for (var j=0; j<=a.length; j++) {
if (c[j] <= c[j+1])
break;
}
}
return sum;
}'
|
JavaScriptParser
parseFunction:'
function switch_time(value) {
if (value < 0.5) sw = 0;
else sw=-1;
}
'
|
JavaScriptParser
parseFunction:'
function f(a) {
return ( function (b) { return (a + b); } );
}
'
|
JavaScriptParser parseExpression:'{a:10 , b:20}'
|
JavaScriptParser parseFunction:'function foo() { var foo = {a:10 , b:20}; }'
|
JavaScriptParser parseExpression:'function foo() { var {a,b} = foo(); }'
|
|