diff --git a/src/FAST-Core-Model/FASTTCanBeLocalDeclaration.trait.st b/src/FAST-Core-Model/FASTTCanBeLocalDeclaration.trait.st new file mode 100644 index 0000000..3ad932c --- /dev/null +++ b/src/FAST-Core-Model/FASTTCanBeLocalDeclaration.trait.st @@ -0,0 +1,20 @@ +" +This trait is here to add API used for the local resolution. + + +" +Trait { + #name : 'FASTTCanBeLocalDeclaration', + #category : 'FAST-Core-Model-Traits', + #package : 'FAST-Core-Model', + #tag : 'Traits' +} + +{ #category : 'meta' } +FASTTCanBeLocalDeclaration classSide >> annotation [ + + + + + +] diff --git a/src/FAST-Core-Model/FASTTEntity.trait.st b/src/FAST-Core-Model/FASTTEntity.trait.st index 74b5528..04a5c4c 100644 --- a/src/FAST-Core-Model/FASTTEntity.trait.st +++ b/src/FAST-Core-Model/FASTTEntity.trait.st @@ -13,11 +13,11 @@ any entity Trait { #name : 'FASTTEntity', #instVars : [ - '#startPos => FMProperty', - '#endPos => FMProperty' + '#endPos => FMProperty', + '#startPos => FMProperty' ], - #traits : 'TEntityMetaLevelDependency', - #classTraits : 'TEntityMetaLevelDependency classTrait', + #traits : 'FASTTCanBeLocalDeclaration + TEntityMetaLevelDependency', + #classTraits : 'FASTTCanBeLocalDeclaration classTrait + TEntityMetaLevelDependency classTrait', #category : 'FAST-Core-Model-Traits', #package : 'FAST-Core-Model', #tag : 'Traits' diff --git a/src/FAST-Core-Tools/FASTNonLocalDeclaration.class.st b/src/FAST-Core-Tools/FASTNonLocalDeclaration.class.st index 847497d..150d792 100644 --- a/src/FAST-Core-Tools/FASTNonLocalDeclaration.class.st +++ b/src/FAST-Core-Tools/FASTNonLocalDeclaration.class.st @@ -4,8 +4,8 @@ A ""null-object"" signaling the declaration of a 'name' was not found Class { #name : 'FASTNonLocalDeclaration', #superclass : 'FASTEntity', - #traits : 'FASTTEntity', - #classTraits : 'FASTTEntity classTrait', + #traits : 'FASTTCanBeLocalDeclaration', + #classTraits : 'FASTTCanBeLocalDeclaration classTrait', #instVars : [ 'name' ], diff --git a/src/FAST-Core-Tools/FASTTCanBeLocalDeclaration.extension.st b/src/FAST-Core-Tools/FASTTCanBeLocalDeclaration.extension.st new file mode 100644 index 0000000..494014a --- /dev/null +++ b/src/FAST-Core-Tools/FASTTCanBeLocalDeclaration.extension.st @@ -0,0 +1,195 @@ +Extension { #name : 'FASTTCanBeLocalDeclaration' } + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> activeVersion [ + "Used for SSA" + + ^ self attributeAt: #activeVersion ifAbsent: [ nil ] +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> activeVersion: aSSAVersion [ + "Used for SSA" + + ^ self attributeAt: #activeVersion put: aSSAVersion +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> addLocalUse: aFASTNode [ + "Used for LocalResolver" + + (self attributeAt: #localUses ifAbsent: [ Error signal: 'missing #localUses attribute in ' , self asString ]) add: aFASTNode +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> allAccesses [ + "For a specific variable, I return all the read and write accesses to the variable. + + Note that the receiver should be a node representing a variable for it to work." + + ^ self localDeclaration localUses +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> allReadAccesses [ + "For a specific variable, I return all the read accesses to the variable. + + Note that the receiver should be a node representing a variable for it to work." + + ^ self localDeclaration localUses reject: [ :access | access isVariableWriteAccess ] +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> allWriteAccesses [ + "For a specific variable, I return all the write accesses to the variable. + + Note that the receiver should be a node representing a variable for it to work." + + ^ self localDeclaration localUses select: [ :access | access isVariableWriteAccess ] +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> assignedExpressions [ + "If I am a node representing an assignment (can be a for each for example), return the expressions used for the assignment. Else return an empty collection" + + ^ self explicitRequirement +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> assignedExpressionsMap [ + + | result | + result := Dictionary new. + + self versionWriteAccesses do: [ :access | result at: access put: access variableDeclaration assignedExpressions ]. + ^ result +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> clearLocalUses [ + "Used for LocalResolver" + + self attributeAt: #localUses put: OrderedCollection new +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> hasLocalDeclaration [ + "Used for LocalResolver" + + ^ self localDeclarationifPresent: [ true ] ifAbsent: [ false ] +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> localDeclaration [ + "Used for LocalResolver" + + ^ self localDeclarationIfAbsent: [ + self error: 'Missing #localDeclaration attribute in ' , self asString , '. It can have multiple sources: +- The local resolution was not done (launch the local resolver visitor or the SSA visitor on your top module) +- The entity is not an entity with a definition +- There is a bug in the local resolver' ] +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> localDeclaration: aDeclarationNode [ + "Used for LocalResolver" + + self attributeAt: #localDeclaration put: aDeclarationNode +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> localDeclarationIfAbsent: aBlock [ + "Used for LocalResolver" + + ^ self attributeAt: #localDeclaration ifAbsent: aBlock +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> localDeclarationifPresent: aBlock ifAbsent: anotherBlock [ + "Used for LocalResolver" + + ^ aBlock cull: (self attributeAt: #localDeclaration ifAbsent: anotherBlock) +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> localUses [ + "Used for LocalResolver" + + ^ self attributeAt: #localUses ifAbsent: [ Error signal: 'missing #localUses attribute in ' , self asString ] +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> localUses: aCollection [ + "Used for LocalResolver" + + self attributeAt: #localUses put: aCollection +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> newVersionNumber [ + "Used for SSA" + + ^ self activeVersion + ifNil: [ 0 ] + ifNotNil: [ :active | active version + 1 ] +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> ssaName [ + "Used for SSA" + + ^ self ssaVersion name +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> ssaVersion [ + "If I represent a variable and we resolved the SSA of my FAST model, I'll return the SSA version I'm linked to." + + ^ self attributeAt: #ssaVersion ifAbsent: [ nil ] +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> ssaVersion: aSSAVersion [ + "Used for SSA" + + self attributeAt: #ssaVersion put: aSSAVersion +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> versionAccesses [ + "For a specific variable, I return all the read and write accesses to the current version of the variable. + + The current version match the current SSA version of the variable. It means that it ill ignore all read and write accesses that cannot impact the currently assigned variable (in case of assignemnts in a conditional, takes all possible versions). + + Note that the receiver should be a node representing a variable for it to work." + + ^ self ssaVersion + ifNil: [ + self error: 'No SSA version available. Possible sources: + - You did not run the SSA resolver + - Your node is not representing a variable + - There is a bug in the SSA or Local resolver' ] + ifNotNil: [ :version | version localUses ] +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> versionReadAccesses [ + "For a specific variable, I return all the read accesses to the current version of the variable. + + The current version match the current SSA version of the variable. It means that it ill ignore all read and write accesses that cannot impact the currently assigned variable (in case of assignemnts in a conditional, takes all possible versions). + + Note that the receiver should be a node representing a variable for it to work." + + ^ self versionAccesses reject: #isVariableWriteAccess +] + +{ #category : '*FAST-Core-Tools' } +FASTTCanBeLocalDeclaration >> versionWriteAccesses [ + "For a specific variable, I return all the write accesses to the current version of the variable. + + The current version match the current SSA version of the variable. It means that it ill ignore all read and write accesses that cannot impact the currently assigned variable (in case of assignemnts in a conditional, takes all possible versions). + + Note that the receiver should be a node representing a variable for it to work." + + ^ self versionAccesses select: #isVariableWriteAccess +] diff --git a/src/FAST-Core-Tools/FASTTEntity.extension.st b/src/FAST-Core-Tools/FASTTEntity.extension.st index b08d92d..ab85c36 100644 --- a/src/FAST-Core-Tools/FASTTEntity.extension.st +++ b/src/FAST-Core-Tools/FASTTEntity.extension.st @@ -1,77 +1,5 @@ Extension { #name : 'FASTTEntity' } -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> activeVersion [ - "Used for SSA" - - ^ self attributeAt: #activeVersion ifAbsent: [ nil ] -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> activeVersion: aSSAVersion [ - "Used for SSA" - - ^ self attributeAt: #activeVersion put: aSSAVersion -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> addLocalUse: aFASTNode [ - "Used for LocalResolver" - - (self attributeAt: #localUses ifAbsent: [ Error signal: 'missing #localUses attribute in ' , self asString ]) add: aFASTNode -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> allAccesses [ - "For a specific variable, I return all the read and write accesses to the variable. - - Note that the receiver should be a node representing a variable for it to work." - - ^ self localDeclaration localUses -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> allReadAccesses [ - "For a specific variable, I return all the read accesses to the variable. - - Note that the receiver should be a node representing a variable for it to work." - - ^ self localDeclaration localUses reject: [ :access | access isVariableWriteAccess ] -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> allWriteAccesses [ - "For a specific variable, I return all the write accesses to the variable. - - Note that the receiver should be a node representing a variable for it to work." - - ^ self localDeclaration localUses select: [ :access | access isVariableWriteAccess ] -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> assignedExpressions [ - "If I am a node representing an assignment (can be a for each for example), return the expressions used for the assignment. Else return an empty collection" - - ^ self explicitRequirement -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> assignedExpressionsMap [ - - | result | - result := Dictionary new. - - self versionWriteAccesses do: [ :access | result at: access put: access variableDeclaration assignedExpressions ]. - ^ result -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> clearLocalUses [ - "Used for LocalResolver" - - self attributeAt: #localUses put: OrderedCollection new -] - { #category : '*FAST-Core-Tools' } FASTTEntity >> dump [ @@ -80,13 +8,6 @@ FASTTEntity >> dump [ ^ FASTDumpVisitor visit: self ] -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> hasLocalDeclaration [ - "Used for LocalResolver" - - ^ self localDeclarationifPresent: [ true ] ifAbsent: [ false ] -] - { #category : '*FAST-Core-Tools' } FASTTEntity >> inspectionFASTDump: aBuilder [ @@ -120,124 +41,9 @@ FASTTEntity >> isVariableWriteAccess [ ^ self variableDeclaration isNotNil ] -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> localDeclaration [ - "Used for LocalResolver" - - ^ self localDeclarationIfAbsent: [ - self error: 'Missing #localDeclaration attribute in ' , self asString , '. It can have multiple sources: -- The local resolution was not done (launch the local resolver visitor or the SSA visitor on your top module) -- The entity is not an entity with a definition -- There is a bug in the local resolver' ] -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> localDeclaration: aDeclarationNode [ - "Used for LocalResolver" - - self attributeAt: #localDeclaration put: aDeclarationNode -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> localDeclarationIfAbsent: aBlock [ - "Used for LocalResolver" - - ^ self attributeAt: #localDeclaration ifAbsent: aBlock -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> localDeclarationifPresent: aBlock ifAbsent: anotherBlock [ - "Used for LocalResolver" - - ^ aBlock cull: (self attributeAt: #localDeclaration ifAbsent: anotherBlock) -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> localUses [ - "Used for LocalResolver" - - ^ self attributeAt: #localUses ifAbsent: [ Error signal: 'missing #localUses attribute in ' , self asString ] -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> localUses: aCollection [ - "Used for LocalResolver" - - self attributeAt: #localUses put: aCollection -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> newVersionNumber [ - "Used for SSA" - - ^ self activeVersion - ifNil: [ 0 ] - ifNotNil: [ :active | active version + 1 ] -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> ssaName [ - "Used for SSA" - - ^ self ssaVersion name -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> ssaVersion [ - "If I represent a variable and we resolved the SSA of my FAST model, I'll return the SSA version I'm linked to." - - ^ self attributeAt: #ssaVersion ifAbsent: [ nil ] -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> ssaVersion: aSSAVersion [ - "Used for SSA" - - self attributeAt: #ssaVersion put: aSSAVersion -] - { #category : '*FAST-Core-Tools' } FASTTEntity >> variableDeclaration [ "If I am a node representing a write access, I should return the node assigning me. Else I return nil." ^ self explicitRequirement ] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> versionAccesses [ - "For a specific variable, I return all the read and write accesses to the current version of the variable. - - The current version match the current SSA version of the variable. It means that it ill ignore all read and write accesses that cannot impact the currently assigned variable (in case of assignemnts in a conditional, takes all possible versions). - - Note that the receiver should be a node representing a variable for it to work." - - ^ self ssaVersion - ifNil: [ - self error: 'No SSA version available. Possible sources: - - You did not run the SSA resolver - - Your node is not representing a variable - - There is a bug in the SSA or Local resolver' ] - ifNotNil: [ :version | version localUses ] -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> versionReadAccesses [ - "For a specific variable, I return all the read accesses to the current version of the variable. - - The current version match the current SSA version of the variable. It means that it ill ignore all read and write accesses that cannot impact the currently assigned variable (in case of assignemnts in a conditional, takes all possible versions). - - Note that the receiver should be a node representing a variable for it to work." - - ^ self versionAccesses reject: #isVariableWriteAccess -] - -{ #category : '*FAST-Core-Tools' } -FASTTEntity >> versionWriteAccesses [ - "For a specific variable, I return all the write accesses to the current version of the variable. - - The current version match the current SSA version of the variable. It means that it ill ignore all read and write accesses that cannot impact the currently assigned variable (in case of assignemnts in a conditional, takes all possible versions). - - Note that the receiver should be a node representing a variable for it to work." - - ^ self versionAccesses select: #isVariableWriteAccess -] diff --git a/src/FAST-Model-Generator/FASTMetamodelGenerator.class.st b/src/FAST-Model-Generator/FASTMetamodelGenerator.class.st index f538967..942e6c1 100644 --- a/src/FAST-Model-Generator/FASTMetamodelGenerator.class.st +++ b/src/FAST-Model-Generator/FASTMetamodelGenerator.class.st @@ -40,7 +40,8 @@ Class { 'tWithCondition', 'tBreakStatement', 'tContinueStatement', - 'tCanBeVariable' + 'tCanBeVariable', + 'tCanBeLocalDeclaration' ], #category : 'FAST-Model-Generator', #package : 'FAST-Model-Generator' @@ -221,6 +222,7 @@ FASTMetamodelGenerator >> defineClasses [ FASTMetamodelGenerator >> defineHierarchy [ super defineHierarchy. tEntity --|> #TEntityMetaLevelDependency. + tEntity --|> tCanBeLocalDeclaration. tExpression --|> tEntity. entity --|> tEntity. @@ -351,6 +353,7 @@ FASTMetamodelGenerator >> defineTraits [ tBreakStatement withTesting. tCanBeVariable := (builder newTraitNamed: #TCanBeVariable) comment: 'Represent everything that can be a variable. Useful for the LocalResolver and the SSA builder.'. tCanBeVariable testingSelector: #canBeVariable. + tCanBeLocalDeclaration := (builder newTraitNamed: #TCanBeLocalDeclaration) comment: 'This trait is here to add API used for the local resolution.'. tCharacterLiteral := builder newTraitNamed: #TCharacterLiteral comment: self commentForTCharacterLiteral. tCharacterLiteral withTesting. tComment := builder newTraitNamed: #TComment.