Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
OpenGEODE
Commits
c17badb7
Commit
c17badb7
authored
Aug 15, 2014
by
dbarbera
Browse files
fix type analysis in call expressions with literal values
parent
c31ea295
Changes
1
Hide whitespace changes
Inline
Side-by-side
ogParser.py
View file @
c17badb7
...
...
@@ -596,36 +596,36 @@ def check_range(typeref, type_to_check):
raise
TypeError
(
'Missing range'
)
def
check_type_compatibility
(
primary
,
type
R
ef
,
context
):
def
check_type_compatibility
(
primary
,
type
_r
ef
,
context
):
'''
Check if an ogAST.Primary (raw value, enumerated, ASN.1 Value...)
is compatible with a given type (type
R
ef is an ASN1Scc type)
is compatible with a given type (type
_r
ef is an ASN1Scc type)
Does not return anything if OK, otherwise raises TypeError
'''
assert
type
R
ef
is
not
None
if
type
R
ef
is
UNKNOWN_TYPE
:
assert
type
_r
ef
is
not
None
if
type
_r
ef
is
UNKNOWN_TYPE
:
raise
TypeError
(
'Type reference is unknown'
)
if
isinstance
(
primary
,
ogAST
.
PrimConstant
):
# ASN.1 constants type is unknown (Asn1 backend to be completed)
return
actual
_type
=
find_basic_type
(
type
R
ef
)
basic
_type
=
find_basic_type
(
type
_r
ef
)
LOG
.
debug
(
"[check_type_compatibility] "
"checking if {value} is of type {typeref}"
.
format
(
value
=
primary
.
inputString
,
typeref
=
type_name
(
type
R
ef
)))
.
format
(
value
=
primary
.
inputString
,
typeref
=
type_name
(
type
_r
ef
)))
if
(
isinstance
(
primary
,
ogAST
.
PrimEnumeratedValue
)
and
actual
_type
.
kind
.
endswith
(
'EnumeratedType'
)):
and
basic
_type
.
kind
.
endswith
(
'EnumeratedType'
)):
# If type ref is an enumeration, check that the value is valid
# Note, when using the "present" operator of a CHOICE type, the
# resulting value is actually an EnumeratedType
enumerant
=
primary
.
inputString
.
replace
(
'_'
,
'-'
)
corr_type
=
actual
_type
.
EnumValues
.
get
(
enumerant
)
corr_type
=
basic
_type
.
EnumValues
.
get
(
enumerant
)
if
corr_type
:
return
else
:
err
=
(
'Value "'
+
primary
.
inputString
+
'" not in this enumeration: '
+
str
(
actual
_type
.
EnumValues
.
keys
()))
str
(
basic
_type
.
EnumValues
.
keys
()))
raise
TypeError
(
err
)
elif
isinstance
(
primary
,
ogAST
.
PrimConditional
):
then_expr
=
primary
.
value
[
'then'
]
...
...
@@ -633,61 +633,62 @@ def check_type_compatibility(primary, typeRef, context):
for
expr
in
(
then_expr
,
else_expr
):
if
expr
.
is_raw
:
check_type_compatibility
(
expr
,
type
R
ef
,
context
)
check_type_compatibility
(
expr
,
type
_r
ef
,
context
)
return
elif
isinstance
(
primary
,
ogAST
.
PrimVariable
):
try
:
compare_types
(
primary
.
exprType
,
type
R
ef
)
compare_types
(
primary
.
exprType
,
type
_r
ef
)
except
TypeError
as
err
:
raise
TypeError
(
'{expr} should be of type {ty} - {err}'
.
format
(
expr
=
primary
.
inputString
,
ty
=
type_name
(
type
R
ef
),
ty
=
type_name
(
type
_r
ef
),
err
=
str
(
err
)))
return
elif
isinstance
(
primary
,
ogAST
.
PrimInteger
)
\
and
actual_type
.
kind
.
startswith
(
'Integer'
)
:
and
is_integer
(
basic_type
)
or
type_ref
==
NUMERICAL
:
return
elif
isinstance
(
primary
,
ogAST
.
PrimReal
)
\
and
actual_type
.
kind
.
startswith
(
'Real'
)
:
and
is_real
(
basic_type
)
or
type_ref
==
NUMERICAL
:
return
elif
isinstance
(
primary
,
ogAST
.
PrimBoolean
)
\
and
actual_type
.
kind
.
startswith
(
'Boolean'
):
elif
isinstance
(
primary
,
ogAST
.
PrimBoolean
)
and
is_boolean
(
basic_type
):
return
elif
(
isinstance
(
primary
,
ogAST
.
PrimEmptyString
)
and
actual
_type
.
kind
==
'SequenceOfType'
):
if
int
(
actual
_type
.
Min
)
==
0
:
basic
_type
.
kind
==
'SequenceOfType'
):
if
int
(
basic
_type
.
Min
)
==
0
:
return
else
:
raise
TypeError
(
'SEQUENCE OF has a minimum size of '
+
actual
_type
.
Min
+
')'
)
+
basic
_type
.
Min
+
')'
)
elif
isinstance
(
primary
,
ogAST
.
PrimSequenceOf
)
\
and
actual
_type
.
kind
==
'SequenceOfType'
:
if
(
len
(
primary
.
value
)
<
int
(
actual
_type
.
Min
)
or
len
(
primary
.
value
)
>
int
(
actual
_type
.
Max
)):
and
basic
_type
.
kind
==
'SequenceOfType'
:
if
(
len
(
primary
.
value
)
<
int
(
basic
_type
.
Min
)
or
len
(
primary
.
value
)
>
int
(
basic
_type
.
Max
)):
raise
TypeError
(
str
(
len
(
primary
.
value
))
+
' elements in SEQUENCE OF, while constraint is ['
+
str
(
actual
_type
.
Min
)
+
'..'
+
str
(
actual
_type
.
Max
)
+
']'
)
str
(
basic
_type
.
Min
)
+
'..'
+
str
(
basic
_type
.
Max
)
+
']'
)
for
elem
in
primary
.
value
:
check_type_compatibility
(
elem
,
actual
_type
.
type
,
context
)
check_type_compatibility
(
elem
,
basic
_type
.
type
,
context
)
return
elif
isinstance
(
primary
,
ogAST
.
PrimSequence
)
\
and
actual
_type
.
kind
==
'SequenceType'
:
and
basic
_type
.
kind
==
'SequenceType'
:
user_nb_elem
=
len
(
primary
.
value
.
keys
())
type_nb_elem
=
len
(
actual
_type
.
Children
.
keys
())
type_nb_elem
=
len
(
basic
_type
.
Children
.
keys
())
if
user_nb_elem
!=
type_nb_elem
:
raise
TypeError
(
'Wrong number of fields in SEQUENCE of type {}'
.
format
(
type_name
(
type
R
ef
)))
.
format
(
type_name
(
type
_r
ef
)))
else
:
for
field
,
fd_data
in
actual
_type
.
Children
.
viewitems
():
for
field
,
fd_data
in
basic
_type
.
Children
.
viewitems
():
ufield
=
field
.
replace
(
'-'
,
'_'
)
if
ufield
not
in
primary
.
value
:
raise
TypeError
(
'Missing field {field} in SEQUENCE'
' of type {t1} '
.
format
(
field
=
ufield
,
t1
=
type_name
(
type
R
ef
)))
t1
=
type_name
(
type
_r
ef
)))
else
:
# If the user field is a raw value
if
primary
.
value
[
ufield
].
is_raw
:
...
...
@@ -705,16 +706,16 @@ def check_type_compatibility(primary, typeRef, context):
' - '
+
str
(
err
))
return
elif
isinstance
(
primary
,
ogAST
.
PrimChoiceItem
)
\
and
actual
_type
.
kind
.
startswith
(
'Choice'
):
for
choicekey
,
choice
in
actual
_type
.
Children
.
viewitems
():
and
basic
_type
.
kind
.
startswith
(
'Choice'
):
for
choicekey
,
choice
in
basic
_type
.
Children
.
viewitems
():
if
choicekey
.
lower
()
==
primary
.
value
[
'choice'
].
lower
():
break
else
:
raise
TypeError
(
'Non-existent choice "{choice}" in type {t1}'
.
format
(
choice
=
primary
.
value
[
'choice'
],
t1
=
type_name
(
type
R
ef
)))
t1
=
type_name
(
type
_r
ef
)))
# compare primary.value['value']
# with
actual
_type['Children'][primary.choiceItem['choice']]
# with
basic
_type['Children'][primary.choiceItem['choice']]
value
=
primary
.
value
[
'value'
]
choice_field_type
=
choice
.
type
# if the user field is a raw value:
...
...
@@ -733,19 +734,19 @@ def check_type_compatibility(primary, typeRef, context):
value
.
exprType
=
choice_field_type
# XXX
return
elif
isinstance
(
primary
,
ogAST
.
PrimChoiceDeterminant
)
\
and
actual
_type
.
kind
.
startswith
(
'Choice'
):
for
choicekey
,
choice
in
actual
_type
.
EnumValues
.
viewitems
():
and
basic
_type
.
kind
.
startswith
(
'Choice'
):
for
choicekey
,
choice
in
basic
_type
.
EnumValues
.
viewitems
():
if
choicekey
.
replace
(
'-'
,
'_'
).
lower
()
==
\
primary
.
inputString
.
lower
():
break
else
:
raise
TypeError
(
'Non-existent choice "{choice}" in type {t1}'
.
format
(
choice
=
primary
.
inputString
,
t1
=
type_name
(
type
R
ef
)))
t1
=
type_name
(
type
_r
ef
)))
elif
isinstance
(
primary
,
ogAST
.
PrimStringLiteral
):
# Octet strings
basic_type
=
find_basic_type
(
type
R
ef
)
basic_type
=
find_basic_type
(
type
_r
ef
)
if
basic_type
.
kind
==
'StandardStringType'
:
return
elif
basic_type
.
kind
.
endswith
(
'StringType'
):
...
...
@@ -759,14 +760,14 @@ def check_type_compatibility(primary, typeRef, context):
else
:
raise
TypeError
(
'String literal not expected'
)
elif
(
isinstance
(
primary
,
ogAST
.
PrimMantissaBaseExp
)
and
actual
_type
.
kind
==
'RealType'
):
basic
_type
.
kind
==
'RealType'
):
LOG
.
debug
(
'PROBABLY (it is a float but I did not check'
'if values are compatible)'
)
return
else
:
raise
TypeError
(
'{prim} does not match type {t1}'
.
format
(
prim
=
primary
.
inputString
,
t1
=
type_name
(
type
R
ef
)))
t1
=
type_name
(
type
_r
ef
)))
def
compare_types
(
type_a
,
type_b
):
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment