amber/st/Compiler-Semantic.st in resin-0.3.1 vs amber/st/Compiler-Semantic.st in resin-0.4.0

- old
+ new

@@ -9,10 +9,14 @@ I am attached to a ScopeVar and method/block nodes. Each context (method/closure) get a fresh scope that inherits from its outer scope.! !LexicalScope methodsFor: 'accessing'! +alias + ^ '$ctx', self scopeLevel asString +! + allVariableNames ^ self args keys, self temps keys ! args @@ -68,13 +72,14 @@ pseudoVars ^ self methodScope pseudoVars ! scopeLevel - ^ (self outerScope - ifNil: [ 0 ] - ifNotNil: [ self outerScope scopeLevel ]) + 1 + self outerScope ifNil: [ ^ 1 ]. + self isInlined ifTrue: [ ^ self outerScope scopeLevel ]. + + ^ self outerScope scopeLevel + 1 ! temps ^ temps ifNil: [ temps := Dictionary new ] ! ! @@ -100,11 +105,12 @@ isBlockScope ^ self isMethodScope not ! isInlined - ^ self instruction isInlined + ^ self instruction notNil and: [ + self instruction isInlined ] ! isMethodScope ^ false ! ! @@ -368,11 +374,11 @@ isUnknownVar ^ true ! ! NodeVisitor subclass: #SemanticAnalyzer - instanceVariableNames: 'currentScope theClass classReferences messageSends' + instanceVariableNames: 'currentScope theClass classReferences messageSends superSends' package: 'Compiler-Semantic'! !SemanticAnalyzer commentStamp! I semantically analyze the abstract syntax tree and annotate it with informations such as non local returns and variable scopes.! !SemanticAnalyzer methodsFor: 'accessing'! @@ -383,10 +389,14 @@ messageSends ^ messageSends ifNil: [ messageSends := Dictionary new ] ! +superSends + ^ superSends ifNil: [ superSends := Dictionary new ] +! + theClass ^ theClass ! theClass: aClass @@ -400,23 +410,28 @@ variableName: aString; signal ! errorUnknownVariable: aNode - "Throw an error if the variable is undeclared in the global JS scope (i.e. window)" + "Throw an error if the variable is undeclared in the global JS scope (i.e. window). + We allow four variable names in addition: `jQuery`, `window`, `process` and `global` + for nodejs and browser environments. + + This is only to make sure compilation works on both browser-based and nodejs environments. + The ideal solution would be to use a pragma instead" - | notDefined | - - notDefined := <eval('typeof ' + aNode._value() + ' == "undefined"')>. - - notDefined - ifTrue: [ - UnknownVariableError new - variableName: aNode value; - signal ] - ifFalse: [ - currentScope methodScope unknownVariables add: aNode value. ] + | identifier | + identifier := aNode value. + + ((#('jQuery' 'window' 'process' 'global') includes: identifier) not + and: [ self isVariableGloballyUndefined: identifier ]) + ifTrue: [ + UnknownVariableError new + variableName: aNode value; + signal ] + ifFalse: [ + currentScope methodScope unknownVariables add: aNode value ] ! ! !SemanticAnalyzer methodsFor: 'factory'! newBlockScope @@ -450,10 +465,16 @@ (currentScope lookupVariable: aString) ifNotNil: [ self errorShadowingVariable: aString ] ! ! +!SemanticAnalyzer methodsFor: 'testing'! + +isVariableGloballyUndefined: aString + <return eval('typeof ' + aString + ' == "undefined"')> +! ! + !SemanticAnalyzer methodsFor: 'visiting'! visitAssignmentNode: aNode super visitAssignmentNode: aNode. aNode left beAssigned @@ -499,11 +520,12 @@ super visitMethodNode: aNode. aNode classReferences: self classReferences; - messageSends: self messageSends keys. + messageSends: self messageSends keys; + superSends: self superSends keys. self popScope ! visitReturnNode: aNode aNode scope: currentScope. @@ -516,13 +538,16 @@ visitSendNode: aNode aNode receiver value = 'super' ifTrue: [ aNode superSend: true. - aNode receiver value: 'self' ] + aNode receiver value: 'self'. + self superSends at: aNode selector ifAbsentPut: [ Set new ]. + (self superSends at: aNode selector) add: aNode ] + ifFalse: [ (IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [ aNode shouldBeInlined: true. - aNode receiver isValueNode ifFalse: [ aNode receiver shouldBeAliased: true ] ] ]. + aNode receiver shouldBeAliased: true ] ]. self messageSends at: aNode selector ifAbsentPut: [ Set new ]. (self messageSends at: aNode selector) add: aNode. aNode index: (self messageSends at: aNode selector) size.