mirror of
https://github.com/nasa/fpp.git
synced 2025-12-10 17:29:15 -06:00
Revise dictionary analysis
This commit is contained in:
parent
e5171fabf6
commit
ca61b2fdca
@ -10,36 +10,31 @@ object CheckDictionaryDefs
|
||||
{
|
||||
|
||||
def checkConstantDef(a: Analysis, s: Symbol.Constant) =
|
||||
if s.isDictionaryDef
|
||||
then
|
||||
if !s.isDictionaryDef
|
||||
then Right(a)
|
||||
else
|
||||
val id = s.getNodeId
|
||||
a.typeMap(id) match {
|
||||
case Type.Integer | _: Type.Float | Type.Boolean | _: Type.String =>
|
||||
Right(a.copy(dictionarySymbolSet = a.dictionarySymbolSet + s))
|
||||
case Type.Enum(enumNode, _, _) =>
|
||||
val enumSymbol = Symbol.Enum(enumNode)
|
||||
Right(a.copy(dictionarySymbolSet = a.dictionarySymbolSet + s + enumSymbol))
|
||||
case _ =>
|
||||
val loc = Locations.get(id)
|
||||
Left(
|
||||
SemanticError.InvalidType(
|
||||
loc, s"dictionary constant defintion must have a primitive, string, or enum type"
|
||||
)
|
||||
)
|
||||
}
|
||||
else Right(a)
|
||||
val t = a.typeMap(id)
|
||||
def result =
|
||||
val a1 = a.copy(dictionarySymbolSet = a.dictionarySymbolSet + s)
|
||||
Right(a1)
|
||||
def error =
|
||||
val loc = Locations.get(id)
|
||||
val msg = "dictionary constant defintion must have a primitive, string, or enum type"
|
||||
Left(SemanticError.InvalidType(loc, msg))
|
||||
t match
|
||||
case _: Type.String | Type.Boolean | _: Type.Enum => result
|
||||
case _ => if t.isNumeric then result else error
|
||||
|
||||
def checkTypeDef(a: Analysis, s: Symbol) =
|
||||
if (s.isDictionaryDef)
|
||||
then for {
|
||||
_ <- a.checkDisplayableType(
|
||||
s.getNodeId,
|
||||
"dictionary type definition must be displayable"
|
||||
)
|
||||
} yield {
|
||||
val ss = UsedSymbols.resolveUses(a, Set(s))
|
||||
a.copy(dictionarySymbolSet = a.dictionarySymbolSet ++ ss)
|
||||
}
|
||||
if s.isDictionaryDef
|
||||
then
|
||||
for {
|
||||
_ <- a.checkDisplayableType(
|
||||
s.getNodeId,
|
||||
"dictionary type definition must be displayable"
|
||||
)
|
||||
} yield a.copy(dictionarySymbolSet = a.dictionarySymbolSet + s)
|
||||
else Right(a)
|
||||
|
||||
override def defAliasTypeAnnotatedNode(a: Analysis, aNode: Ast.Annotated[AstNode[Ast.DefAliasType]]) =
|
||||
|
||||
@ -13,50 +13,43 @@ final case class DictionaryUsedSymbols(a: Analysis, t: Topology) {
|
||||
val impliedUses = kinds.flatMap(
|
||||
k => a.getImpliedUses(k, t.aNode._2.id).map(iu => a.useDefMap(iu.id))
|
||||
)
|
||||
Set.concat(
|
||||
val ss = Set.concat(
|
||||
t.instanceMap.keys.toSet.flatMap(getUsedSymbolsForInstance),
|
||||
impliedUses,
|
||||
impliedUses.flatMap(resolveUses),
|
||||
a.dictionarySymbolSet
|
||||
)
|
||||
|
||||
private def resolveUses(s: Symbol) =
|
||||
s match
|
||||
case _: Symbol.Constant =>
|
||||
a.typeMap(s.getNodeId) match
|
||||
case t: Type.Enum => Set(Symbol.Enum(t.node))
|
||||
case _ => Set()
|
||||
case _ => UsedSymbols.resolveUses(a, Set(s))
|
||||
UsedSymbols.resolveUses(a, ss)
|
||||
|
||||
private def getUsedSymbolsForInstance(ci: ComponentInstance) = {
|
||||
val component = ci.component
|
||||
val a1 = a.copy(usedSymbolSet = Set())
|
||||
val commandSymbols = getUsedSymbolsForSpecifier(
|
||||
component.commandMap,
|
||||
{
|
||||
case Command.NonParam(aNode, _) =>
|
||||
UsedSymbols.specCommandAnnotatedNode(a, aNode)
|
||||
UsedSymbols.specCommandAnnotatedNode(a1, aNode)
|
||||
case _ => Right(a.copy(usedSymbolSet = Set()))
|
||||
}
|
||||
)
|
||||
val eventSymbols = getUsedSymbolsForSpecifier(
|
||||
component.eventMap,
|
||||
event => UsedSymbols.specEventAnnotatedNode(a, event.aNode)
|
||||
event => UsedSymbols.specEventAnnotatedNode(a1, event.aNode)
|
||||
)
|
||||
val tlmChannelSymbols = getUsedSymbolsForSpecifier(
|
||||
component.tlmChannelMap,
|
||||
channel => UsedSymbols.specTlmChannelAnnotatedNode(a, channel.aNode)
|
||||
channel => UsedSymbols.specTlmChannelAnnotatedNode(a1, channel.aNode)
|
||||
)
|
||||
val paramSymbols = getUsedSymbolsForSpecifier(
|
||||
component.paramMap,
|
||||
param => UsedSymbols.specParamAnnotatedNode(a, param.aNode)
|
||||
param => UsedSymbols.specParamAnnotatedNode(a1, param.aNode)
|
||||
)
|
||||
val recordSymbols = getUsedSymbolsForSpecifier(
|
||||
component.recordMap,
|
||||
record => UsedSymbols.specRecordAnnotatedNode(a, record.aNode)
|
||||
record => UsedSymbols.specRecordAnnotatedNode(a1, record.aNode)
|
||||
)
|
||||
val containerSymbols = getUsedSymbolsForSpecifier(
|
||||
component.containerMap,
|
||||
container => UsedSymbols.specContainerAnnotatedNode(a, container.aNode)
|
||||
container => UsedSymbols.specContainerAnnotatedNode(a1, container.aNode)
|
||||
)
|
||||
Set.concat(
|
||||
commandSymbols,
|
||||
@ -72,11 +65,11 @@ final case class DictionaryUsedSymbols(a: Analysis, t: Topology) {
|
||||
map: Map[BigInt, Specifier],
|
||||
usedSymbols: Specifier => Result.Result[Analysis]
|
||||
): Set[Symbol] =
|
||||
map.values.toSet.flatMap {
|
||||
map.values.toSet.flatMap (
|
||||
specifier => {
|
||||
val Right(a) = usedSymbols(specifier)
|
||||
UsedSymbols.resolveUses(a, a.usedSymbolSet)
|
||||
a.usedSymbolSet
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ object UsedSymbols extends UseAnalyzer {
|
||||
node: AstNode[Ast.TypeName],
|
||||
use: Name.Qualified
|
||||
) = addSymbol(a, node)
|
||||
|
||||
|
||||
override def portUse(
|
||||
a: Analysis,
|
||||
node: AstNode[Ast.QualIdent],
|
||||
@ -62,6 +62,12 @@ object UsedSymbols extends UseAnalyzer {
|
||||
/** Resolves used symbols recursively */
|
||||
def resolveUses(a: Analysis, ss: Set[Symbol]): Set[Symbol] = {
|
||||
val a1: Analysis = a.copy(usedSymbolSet = Set())
|
||||
def addEnumTypeForEnumConstant(s: Symbol) =
|
||||
s match
|
||||
case Symbol.EnumConstant(node) =>
|
||||
val t @ Type.Enum(enumNode, _, _) = a.typeMap(node._2.id)
|
||||
Set(s, Symbol.Enum(enumNode))
|
||||
case _ => Set(s)
|
||||
def helper(s: Symbol): Set[Symbol] = {
|
||||
val Right(a2) = s match {
|
||||
case Symbol.AbsType(node) => defAbsTypeAnnotatedNode(a1, node)
|
||||
@ -81,7 +87,7 @@ object UsedSymbols extends UseAnalyzer {
|
||||
}
|
||||
a2.usedSymbolSet.flatMap(helper) + s
|
||||
}
|
||||
ss.flatMap(helper)
|
||||
ss.flatMap(helper).flatMap(addEnumTypeForEnumConstant)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6225,12 +6225,6 @@
|
||||
|
||||
},
|
||||
"dictionarySymbolSet" : [
|
||||
{
|
||||
"Array" : {
|
||||
"nodeId" : 104,
|
||||
"unqualifiedName" : "SignalPairSet"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Constant" : {
|
||||
"nodeId" : 1,
|
||||
@ -6260,12 +6254,6 @@
|
||||
"nodeId" : 108,
|
||||
"unqualifiedName" : "SignalSet"
|
||||
}
|
||||
},
|
||||
{
|
||||
"Struct" : {
|
||||
"nodeId" : 99,
|
||||
"unqualifiedName" : "SignalPair"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -4401,7 +4401,10 @@ expression appearing in <em>D</em> must have one of the following types:</p>
|
||||
<div class="ulist">
|
||||
<ul>
|
||||
<li>
|
||||
<p>A <a href="#Types_Primitive-Types">primitive type</a>.</p>
|
||||
<p>A <a href="#Types_Internal-Types_Numeric-Types">numeric type</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <a href="#Types_The-Boolean-Type">Boolean type</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>A <a href="#Types_String-Types">string type</a>.</p>
|
||||
@ -4426,8 +4429,7 @@ dictionary constant b = E.X
|
||||
type T1
|
||||
dictionary type T2 = T1 # Error: T2 is not displayable
|
||||
|
||||
# Error: c does not have primitive, string, or enum type
|
||||
dictionary constant c = { x = U32 }</code></pre>
|
||||
dictionary constant c = { x = U32 } # Error: struct type is not allowed</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -12035,7 +12037,7 @@ equivalent.</p>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2025-10-28 20:24:16 -0700
|
||||
Last updated 2025-10-29 18:57:16 -0700
|
||||
</div>
|
||||
</div>
|
||||
<script src="code-prettify/run_prettify.js"></script>
|
||||
|
||||
@ -14,7 +14,8 @@ defined by _D_ must be a <<Types_Displayable-Types, displayable type>>.
|
||||
If a constant definition _D_ is a dictionary definition, then the
|
||||
expression appearing in _D_ must have one of the following types:
|
||||
|
||||
* A <<Types_Primitive-Types,primitive type>>.
|
||||
* A <<Types_Internal-Types_Numeric-Types,numeric type>>.
|
||||
* The <<Types_The-Boolean-Type,Boolean type>>.
|
||||
* A <<Types_String-Types,string type>>.
|
||||
* An <<Types_Enum-Types,enum type>>.
|
||||
|
||||
@ -32,6 +33,5 @@ dictionary constant b = E.X
|
||||
type T1
|
||||
dictionary type T2 = T1 # Error: T2 is not displayable
|
||||
|
||||
# Error: c does not have primitive, string, or enum type
|
||||
dictionary constant c = { x = U32 }
|
||||
dictionary constant c = { x = U32 } # Error: struct type is not allowed
|
||||
----
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user