nitc :: AAttrPropdef
For historical reason, old-syle and new-style attributes use the same ANode
sub-class
nitc :: AAttrPropdef :: _mlazypropdef
The guard associated to a lazy attribute.nitc :: AAttrPropdef :: _mreadpropdef
The associated getter (read accessor) if anynitc :: AAttrPropdef :: _mtype
The static type of the property (declared, inferred or inherited)nitc :: AAttrPropdef :: _mwritepropdef
The associated setter (write accessor) if anynitc :: AAttrPropdef :: _n_block
The initial value, if any (set withdo return
)
nitc :: AAttrPropdef :: _n_expr
The initial value, if any (set with=
)
nitc :: AAttrPropdef :: _n_type
The declared type of the attributenitc :: AAttrPropdef :: _serialize_name
Name of this attribute in the serialized formatnitc :: AAttrPropdef :: build_attribute_property
Build the attribute propertynitc :: AAttrPropdef :: build_lazy_property
Build the lazy attribute propertynitc :: AAttrPropdef :: build_read_property
Build the read method property to get the value of the attributenitc :: AAttrPropdef :: build_read_signature
Build the read method signaturenitc :: AAttrPropdef :: build_write_property
Build the write method property to set the attribute valuenitc :: AAttrPropdef :: build_write_signature
Build the write method signaturenitc :: AAttrPropdef :: check_expr
nitc :: AAttrPropdef :: compile_getter
Compile the getter methodnitc :: AAttrPropdef :: compile_setter
Compile the setter methodnitc :: AAttrPropdef :: create_setter
Create a new setter for the attribute.nitc :: AAttrPropdef :: defaultinit
nitc :: AAttrPropdef :: define_as_optional
Setself
as optional
nitc :: AAttrPropdef :: define_default
Set the defaultself
value
nitc :: AAttrPropdef :: evaluate_expr
nitc :: AAttrPropdef :: evaluate_expr
Evaluate, store and return the default value of the attributenitc :: AAttrPropdef :: evaluate_expr
Evaluate, store and return the default value of the attributenitc :: AAttrPropdef :: has_value=
Does the node have a default value?nitc :: AAttrPropdef :: infer_static_type
Detect the static type from the value assigned to the attributeself
nitc :: AAttrPropdef :: init_expr
nitc :: AAttrPropdef :: init_expr
nitc :: AAttrPropdef :: init_expr
Evaluate and set the default value of the attribute inrecv
nitc :: AAttrPropdef :: is_optional=
Is the node tagged optional?nitc :: AAttrPropdef :: make
Create a newAAttrPropdef
nitc :: AAttrPropdef :: mlazypropdef
The guard associated to a lazy attribute.nitc :: AAttrPropdef :: mlazypropdef=
The guard associated to a lazy attribute.nitc :: AAttrPropdef :: mreadpropdef
The associated getter (read accessor) if anynitc :: AAttrPropdef :: mreadpropdef=
The associated getter (read accessor) if anynitc :: AAttrPropdef :: mtype
The static type of the property (declared, inferred or inherited)nitc :: AAttrPropdef :: mtype=
The static type of the property (declared, inferred or inherited)nitc :: AAttrPropdef :: mwritepropdef
The associated setter (write accessor) if anynitc :: AAttrPropdef :: mwritepropdef=
The associated setter (write accessor) if anynitc :: AAttrPropdef :: n_block
The initial value, if any (set withdo return
)
nitc :: AAttrPropdef :: n_block=
The initial value, if any (set withdo return
)
nitc :: AAttrPropdef :: n_expr=
The initial value, if any (set with=
)
nitc :: AAttrPropdef :: n_type=
The declared type of the attributenitc :: AAttrPropdef :: serialize_name
Name of this attribute in the serialized formatnitc :: AAttrPropdef :: serialize_name=
Name of this attribute in the serialized formatnitc :: modelize_property $ AAttrPropdef :: MPROPDEF
The associated main model entitynitc $ AAttrPropdef :: SELF
Type of this instance, automatically specialized in every classnitc :: pretty $ AAttrPropdef :: accept_pretty_printer
Start visit ofself
using a PrettyPrinterVisitor
nitc :: naive_interpreter $ AAttrPropdef :: call
Execute ampropdef
associated with the current node.
nitc :: abstract_compiler $ AAttrPropdef :: can_inline
nitc :: modelize_property $ AAttrPropdef :: check_repeated_types
Type is useless if the attribute type is the same thant the intro.nitc :: java_compiler $ AAttrPropdef :: compile_to_java
Compile that property definition to java codenitc :: htmlight $ AAttrPropdef :: decorate_tag
Add aditionnal information on a child-token and return an additionnal HInfoBox on itnitc :: typing $ AAttrPropdef :: do_typing
The entry point of the whole typing analysisnitc :: pretty $ AAttrPropdef :: first_token
The first token of the production in the ASTnitc :: ssa $ AAttrPropdef :: generate_basic_blocks
Generate all basic blocks for this codenitc $ AAttrPropdef :: hot_location
The location of the important part of the node (identifier or whatever)nitc :: separate_compiler $ AAttrPropdef :: init_expr
nitc :: pretty $ AAttrPropdef :: is_inlinable
Isself
printable in one line?
nitc :: parser_prod $ AAttrPropdef :: n_annotations=
All the annotations attached directly to the nodenitc :: parser_prod $ AAttrPropdef :: n_assign=
The=
symbol
nitc :: parser_prod $ AAttrPropdef :: n_block=
The initial value, if any (set withdo return
)
nitc :: parser_prod $ AAttrPropdef :: n_doc=
The documentationnitc :: parser_prod $ AAttrPropdef :: n_expr=
The initial value, if any (set with=
)
nitc :: parser_prod $ AAttrPropdef :: n_id2=
The identifier for a new-style attributenitc :: parser_prod $ AAttrPropdef :: n_kwdo=
Thedo
keyword
nitc :: parser_prod $ AAttrPropdef :: n_kwend=
Theend
keyword
nitc :: parser_prod $ AAttrPropdef :: n_kwredef=
Theredef
keyword
nitc :: parser_prod $ AAttrPropdef :: n_type=
The declared type of the attributenitc :: parser_prod $ AAttrPropdef :: n_visibility=
The declared visibilitynitc :: variables_numbering $ AAttrPropdef :: numbering_variables
Assign a position in the environment to each local variablenitc :: parser_prod $ AAttrPropdef :: replace_child
Replace a child with an other node in the ASTnitc :: parser_prod $ AAttrPropdef :: visit_all
Visit all nodes in order.nitc :: APropdef :: _after_flow_context
The ending flownitc :: APropdef :: _basic_block
The first basic block of the codenitc :: APropdef :: _before_flow_context
The starting flownitc :: APropdef :: _environment_size
The size of the environment to create to call this methodnitc :: Prod :: _first_location
Location on the first token after the start of a productionnitc :: Prod :: _first_token
The first token of the production in the ASTnitc :: ANode :: _is_broken
The indication that the node did not pass some semantic verifications.nitc :: APropdef :: _is_compiled
Indicite if this propdef was compilenitc :: APropdef :: _is_generated
If true, the basic blocks where generatednitc :: APropdef :: _is_numbering
Indicate if the variables numbering has been donenitc :: APropdef :: _is_phased
Is the propdef already analyzed byrun_phases_on_npropdef
.
nitc :: Prod :: _last_token
The last token of the production in the ASTnitc :: AAttrPropdef :: _mlazypropdef
The guard associated to a lazy attribute.nitc :: AAttrPropdef :: _mreadpropdef
The associated getter (read accessor) if anynitc :: AAttrPropdef :: _mtype
The static type of the property (declared, inferred or inherited)nitc :: AAttrPropdef :: _mwritepropdef
The associated setter (write accessor) if anynitc :: Prod :: _n_annotations
All the annotations attached directly to the nodenitc :: AAttrPropdef :: _n_block
The initial value, if any (set withdo return
)
nitc :: AAttrPropdef :: _n_expr
The initial value, if any (set with=
)
nitc :: AAttrPropdef :: _n_type
The declared type of the attributenitc :: ADefinition :: _n_visibility
The declared visibilitynitc :: APropdef :: _object_sites
Contain all AST-parts related to object mechanisms the propdef has:nitc :: APropdef :: _return_mark
The break escape mark associated with the returnnitc :: APropdef :: _selfvariable
The variable associated to the receiver (if any)nitc :: AAttrPropdef :: _serialize_name
Name of this attribute in the serialized formatnitc :: APropdef :: _variables
The variables contained in the body on this propdefnitc :: ANode :: accept_ast_validation
nitc :: ANode :: accept_auto_super_init
nitc :: ANode :: accept_flow_visitor
nitc :: ANode :: accept_forward_analysis
Apply the forward analysisv
to self
.
nitc :: ANode :: accept_literal
nitc :: ANode :: accept_post_typing
nitc :: ANode :: accept_pretty_printer
Start visit ofself
using a PrettyPrinterVisitor
nitc :: ANode :: accept_reaching_defs
Apply a ReachingDefsAnalysis toself
.
nitc :: ANode :: accept_regex_visitor
nitc :: ANode :: accept_scope_visitor
nitc :: ANode :: accept_simple_misc
nitc :: ANode :: accept_string_finder
nitc :: APropdef :: after_flow_context=
The ending flownitc :: ANode :: after_simple_misc
nitc :: ANode :: bad_expr_message
An additional information message to explain the role of a child expression.nitc :: APropdef :: basic_block
The first basic block of the codenitc :: APropdef :: basic_block=
The first basic block of the codenitc :: APropdef :: before_flow_context
The starting flownitc :: APropdef :: before_flow_context=
The starting flownitc :: AAttrPropdef :: build_attribute_property
Build the attribute propertynitc :: AAttrPropdef :: build_lazy_property
Build the lazy attribute propertynitc :: APropdef :: build_property
nitc :: AAttrPropdef :: build_read_property
Build the read method property to get the value of the attributenitc :: AAttrPropdef :: build_read_signature
Build the read method signaturenitc :: APropdef :: build_signature
nitc :: AAttrPropdef :: build_write_property
Build the write method property to set the attribute valuenitc :: AAttrPropdef :: build_write_signature
Build the write method signaturempropdef
associated with the current node.
nitc :: APropdef :: can_inline
nitc :: ANode :: check_callsite
nitc :: AAttrPropdef :: check_expr
nitc :: APropdef :: check_redef_keyword
nitc :: APropdef :: check_repeated_types
Checks for useless type in redef signatures.nitc :: APropdef :: check_signature
core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
nitc :: ANode :: collect_annotations_by_name
Do a deep search and return an array of node that are annotatednitc :: Prod :: collect_comments
Collect allTComment
contained in the production
nitc :: ANode :: collect_length
Collect the length (inChar
) of the node.
nitc :: ANode :: collect_tokens_by_text
Do a deep search and return an array of tokens that match a given textnitc :: ANode :: common_parent
The most specific common parent betweenself
and other
nitc :: AAttrPropdef :: compile_getter
Compile the getter methodnitc :: AAttrPropdef :: compile_setter
Compile the setter methodnitc :: APropdef :: compile_to_c
nitc :: APropdef :: compile_to_java
Compile that property definition to java codenitc :: APropdef :: compute_phi
Compute the first phase of SSA algorithm: placing phi-functionsnitc :: ANode :: create_contracts
nitc :: AAttrPropdef :: create_setter
Create a new setter for the attribute.nitc :: ANode :: decorate_tag
Add aditionnal information on a child-token and return an additionnal HInfoBox on itnitc :: ANode :: defaultinit
nitc :: APropdef :: defaultinit
core :: Cloneable :: defaultinit
nitc :: ADefinition :: defaultinit
nitc :: Prod :: defaultinit
nitc :: AAttrPropdef :: defaultinit
core :: Object :: defaultinit
nitc :: AAttrPropdef :: define_as_optional
Setself
as optional
nitc :: AAttrPropdef :: define_default
Set the defaultself
value
nitc :: ANode :: do_cloneable
nitc :: APropdef :: do_local_var_init
Entry point of the whole local variable initialization verifiernitc :: APropdef :: environment_size
The size of the environment to create to call this methodnitc :: APropdef :: environment_size=
The size of the environment to create to call this methodnitc :: AAttrPropdef :: evaluate_expr
Evaluate, store and return the default value of the attributenitc :: AAttrPropdef :: evaluate_expr
Evaluate, store and return the default value of the attributenitc :: AAttrPropdef :: evaluate_expr
nitc :: Prod :: first_location
Location on the first token after the start of a productionnitc :: Prod :: first_location=
Location on the first token after the start of a productionnitc :: Prod :: first_token
The first token of the production in the ASTnitc :: Prod :: first_token=
The first token of the production in the ASTnitc :: ANode :: force_block=
Forceself
to be rendered as a block.
nitc :: ANode :: force_inline=
Forceself
to be rendered as a line.
nitc :: ANode :: full_transform_visitor
nitc :: APropdef :: generate_basic_blocks
Generate all basic blocks for this codenitc :: Prod :: get_annotations
Return all its annotations of a given name in the order of their declarationnitc :: Prod :: get_single_annotation
Try to get its single annotation with a given namenitc :: AAttrPropdef :: has_value=
Does the node have a default value?nitc :: ANode :: hot_location
The location of the important part of the node (identifier or whatever)nitc :: AAttrPropdef :: infer_static_type
Detect the static type from the value assigned to the attributeself
nitc :: AAttrPropdef :: init_expr
nitc :: AAttrPropdef :: init_expr
nitc :: AAttrPropdef :: init_expr
Evaluate and set the default value of the attribute inrecv
nitc :: ANode :: is_broken=
The indication that the node did not pass some semantic verifications.nitc :: APropdef :: is_compiled=
Indicite if this propdef was compilenitc :: APropdef :: is_generated=
If true, the basic blocks where generatednitc :: ANode :: is_noserialize
Is this node annotated to not be made serializable?nitc :: APropdef :: is_numbering
Indicate if the variables numbering has been donenitc :: APropdef :: is_numbering=
Indicate if the variables numbering has been donenitc :: AAttrPropdef :: is_optional=
Is the node tagged optional?nitc :: APropdef :: is_phased=
Is the propdef already analyzed byrun_phases_on_npropdef
.
core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
nitc :: ANode :: is_serialize
Is this node annotated to be made serializable?nitc :: ANode :: is_structural
Isself
a token or a pure-structural production like AQId
?
nitc :: Prod :: last_token
The last token of the production in the ASTnitc :: Prod :: last_token=
The last token of the production in the ASTnitc :: AAttrPropdef :: make
Create a newAAttrPropdef
nitc :: AAttrPropdef :: mlazypropdef
The guard associated to a lazy attribute.nitc :: AAttrPropdef :: mlazypropdef=
The guard associated to a lazy attribute.nitc :: AAttrPropdef :: mreadpropdef
The associated getter (read accessor) if anynitc :: AAttrPropdef :: mreadpropdef=
The associated getter (read accessor) if anynitc :: AAttrPropdef :: mtype
The static type of the property (declared, inferred or inherited)nitc :: AAttrPropdef :: mtype=
The static type of the property (declared, inferred or inherited)nitc :: ANode :: must_be_block
Doesself
have to be rendered as a block?
nitc :: ANode :: must_be_inline
Doesself
have be rendered as a line?
nitc :: AAttrPropdef :: mwritepropdef
The associated setter (write accessor) if anynitc :: AAttrPropdef :: mwritepropdef=
The associated setter (write accessor) if anynitc :: Prod :: n_annotations
All the annotations attached directly to the nodenitc :: Prod :: n_annotations=
All the annotations attached directly to the nodenitc :: AAttrPropdef :: n_block
The initial value, if any (set withdo return
)
nitc :: AAttrPropdef :: n_block=
The initial value, if any (set withdo return
)
nitc :: AAttrPropdef :: n_expr=
The initial value, if any (set with=
)
nitc :: AAttrPropdef :: n_type=
The declared type of the attributenitc :: ADefinition :: n_visibility=
The declared visibilitycore :: Object :: native_class_name
The class name of the object in CString format.nitc :: APropdef :: numbering_variables
Numbering the variable inside the propdefnitc :: APropdef :: object_sites
Contain all AST-parts related to object mechanisms the propdef has:nitc :: APropdef :: object_sites=
Contain all AST-parts related to object mechanisms the propdef has:core :: Object :: output_class_name
Display class name on stdout (debug only).nitc :: ANode :: parentize_tokens
Visit the AST and computes advanced AST attributes on Tokens and Prodnitc :: APropdef :: propagate_dependences
Propagate the dependences of the phi-functions into following variablesnitc :: APropdef :: rename_variables
Compute the second phase of SSA algorithm: renaming variablesnitc :: ANode :: replace_child
Replace a child with an other node in the ASTnitc :: ANode :: replace_with
Replace itself with an other node in the ASTnitc :: APropdef :: return_mark
The break escape mark associated with the returnnitc :: APropdef :: return_mark=
The break escape mark associated with the returnnitc :: APropdef :: returnvar=
The return variable of the propdefnitc :: APropdef :: selfvariable
The variable associated to the receiver (if any)nitc :: APropdef :: selfvariable=
The variable associated to the receiver (if any)nitc :: AAttrPropdef :: serialize_name
Name of this attribute in the serialized formatnitc :: AAttrPropdef :: serialize_name=
Name of this attribute in the serialized formatnitc :: APropdef :: ssa_destruction
Transform SSA-representation into an executable code (delete phi-functions)nitc :: Prod :: start_token
The token where the production really start (skipping ADoc).nitc :: APropdef :: variables=
The variables contained in the body on this propdefnitc :: APropdef :: visit_annotations
Factorize annotations visit for all APropdef.nitc :: APropdef :: visit_block
Factorize block visit for APropdefs.nitc :: ANode :: was_inline
Doesself
was written in one line before transformation?
# A definition of an attribute
# For historical reason, old-syle and new-style attributes use the same `ANode` sub-class
class AAttrPropdef
super APropdef
# The `var` keyword
var n_kwvar: TKwvar is writable, noinit
# The identifier for a new-style attribute
var n_id2: TId is writable, noinit
# The declared type of the attribute
var n_type: nullable AType = null is writable
# The `=` symbol
var n_assign: nullable TAssign = null is writable
# The initial value, if any (set with `=`)
var n_expr: nullable AExpr = null is writable
# The `do` keyword
var n_kwdo: nullable TKwdo = null is writable
# The initial value, if any (set with `do return`)
var n_block: nullable AExpr = null is writable
# The `end` keyword
var n_kwend: nullable TKwend = null is writable
redef fun hot_location
do
return n_id2.location
end
end
src/parser/parser_nodes.nit:1369,1--1402,3
redef class AAttrPropdef
init init_aattrpropdef (
n_doc: nullable ADoc,
n_kwredef: nullable TKwredef,
n_visibility: nullable AVisibility,
n_kwvar: nullable TKwvar,
n_id2: nullable TId,
n_type: nullable AType,
n_assign: nullable TAssign,
n_expr: nullable AExpr,
n_annotations: nullable AAnnotations,
n_kwdo: nullable TKwdo,
n_block: nullable AExpr,
n_kwend: nullable TKwend
)
do
_n_doc = n_doc
if n_doc != null then n_doc.parent = self
_n_kwredef = n_kwredef
if n_kwredef != null then n_kwredef.parent = self
_n_visibility = n_visibility.as(not null)
n_visibility.parent = self
_n_kwvar = n_kwvar.as(not null)
n_kwvar.parent = self
_n_id2 = n_id2.as(not null)
n_id2.parent = self
_n_type = n_type
if n_type != null then n_type.parent = self
_n_assign = n_assign
if n_assign != null then n_assign.parent = self
_n_expr = n_expr
if n_expr != null then n_expr.parent = self
_n_annotations = n_annotations
if n_annotations != null then n_annotations.parent = self
_n_kwdo = n_kwdo
if n_kwdo != null then n_kwdo.parent = self
_n_block = n_block
if n_block != null then n_block.parent = self
_n_kwend = n_kwend
if n_kwend != null then n_kwend.parent = self
end
redef fun replace_child(old_child: ANode, new_child: nullable ANode)
do
if _n_doc == old_child then
n_doc = new_child.as(nullable ADoc)
return
end
if _n_kwredef == old_child then
n_kwredef = new_child.as(nullable TKwredef)
return
end
if _n_visibility == old_child then
n_visibility = new_child.as(AVisibility)
return
end
if _n_kwvar == old_child then
n_kwvar = new_child.as(TKwvar)
return
end
if _n_id2 == old_child then
n_id2 = new_child.as(TId)
return
end
if _n_type == old_child then
n_type = new_child.as(nullable AType)
return
end
if _n_assign == old_child then
n_assign = new_child.as(nullable TAssign)
return
end
if _n_expr == old_child then
n_expr = new_child.as(nullable AExpr)
return
end
if _n_annotations == old_child then
n_annotations = new_child.as(nullable AAnnotations)
return
end
if _n_kwdo == old_child then
n_kwdo = new_child.as(nullable TKwdo)
return
end
if _n_block == old_child then
n_block = new_child.as(nullable AExpr)
return
end
if _n_kwend == old_child then
n_kwend = new_child.as(nullable TKwend)
return
end
end
redef fun n_doc=(node)
do
_n_doc = node
if node != null then node.parent = self
end
redef fun n_kwredef=(node)
do
_n_kwredef = node
if node != null then node.parent = self
end
redef fun n_visibility=(node)
do
_n_visibility = node
node.parent = self
end
redef fun n_kwvar=(node)
do
_n_kwvar = node
node.parent = self
end
redef fun n_id2=(node)
do
_n_id2 = node
node.parent = self
end
redef fun n_type=(node)
do
_n_type = node
if node != null then node.parent = self
end
redef fun n_assign=(node)
do
_n_assign = node
if node != null then node.parent = self
end
redef fun n_expr=(node)
do
_n_expr = node
if node != null then node.parent = self
end
redef fun n_annotations=(node)
do
_n_annotations = node
if node != null then node.parent = self
end
redef fun n_kwdo=(node)
do
_n_kwdo = node
if node != null then node.parent = self
end
redef fun n_block=(node)
do
_n_block = node
if node != null then node.parent = self
end
redef fun n_kwend=(node)
do
_n_kwend = node
if node != null then node.parent = self
end
redef fun visit_all(v: Visitor)
do
v.enter_visit(_n_doc)
v.enter_visit(_n_kwredef)
v.enter_visit(_n_visibility)
v.enter_visit(_n_kwvar)
v.enter_visit(_n_id2)
v.enter_visit(_n_type)
v.enter_visit(_n_assign)
v.enter_visit(_n_expr)
v.enter_visit(_n_annotations)
v.enter_visit(_n_kwdo)
v.enter_visit(_n_block)
v.enter_visit(_n_kwend)
end
end
src/parser/parser_prod.nit:819,1--990,3
redef class AAttrPropdef
redef type MPROPDEF: MAttributeDef
# The static type of the property (declared, inferred or inherited)
# This attribute is also used to check if the property was analyzed and is valid.
var mtype: nullable MType
# Is the node tagged `noinit`?
var noinit = false
# Is the node tagged lazy?
var is_lazy = false
# Is the node tagged optional?
var is_optional = false
# Does the node have a default value?
# Could be through `n_expr`, `n_block` or `is_lazy`
var has_value = false
# The name of the attribute
# Note: The name of the attribute is in reality the name of the mreadpropdef
var name: String = n_id2.text is lazy
# The guard associated to a lazy attribute.
# Because some engines does not have a working `isset`,
# this additional attribute is used to guard the lazy initialization.
# TODO: to remove once isset is correctly implemented
var mlazypropdef: nullable MAttributeDef
# The associated getter (read accessor) if any
var mreadpropdef: nullable MMethodDef is writable
# The associated setter (write accessor) if any
var mwritepropdef: nullable MMethodDef is writable
redef fun build_property(modelbuilder, mclassdef)
do
var mclass = mclassdef.mclass
var atabstract = self.get_single_annotation("abstract", modelbuilder)
if atabstract == null then build_attribute_property(modelbuilder, mclassdef)
# Construction of the read property. If it's not correctly built just return.
if not build_read_property(modelbuilder, mclassdef) then return
if atabstract != null then mreadpropdef.is_abstract = true
has_value = n_expr != null or n_block != null
if atabstract != null and has_value then
modelbuilder.error(atabstract, "Error: `abstract` attributes cannot have an initial value.")
return
end
var atnoinit = self.get_single_annotation("noinit", modelbuilder)
if atnoinit == null then atnoinit = self.get_single_annotation("noautoinit", modelbuilder)
if atnoinit != null then
noinit = true
if has_value then
modelbuilder.error(atnoinit, "Error: `noautoinit` attributes cannot have an initial value.")
return
end
if atabstract != null then
modelbuilder.warning(atnoinit, "useless-noautoinit", "Warning: superfluous `noautoinit` on abstract attribute.")
end
end
# Construction of the read property. If it's not correctly built just return.
if not build_lazy_property(modelbuilder, mclassdef) then return
var atoptional = self.get_single_annotation("optional", modelbuilder)
if atoptional != null then
if not has_value then
modelbuilder.error(atoptional, "Error: `optional` attributes need a default value.")
end
is_optional = true
end
var atreadonly = self.get_single_annotation("readonly", modelbuilder)
if atreadonly != null then
if not has_value then
modelbuilder.error(atreadonly, "Error: `readonly` attributes need a value.")
end
# No setter, so just leave
return
end
if not mclassdef.is_intro and not has_value and not noinit then
modelbuilder.advice(self, "attr-in-refinement", "Warning: attributes in refinement need a value or `noautoinit`.")
end
# Construction of the read property. If it's not correctly built just return.
if not build_write_property(modelbuilder, mclassdef, false) then return
if atabstract != null then mwritepropdef.is_abstract = true
var atautoinit = self.get_single_annotation("autoinit", modelbuilder)
if atautoinit != null then
if has_value then
modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot have an initial value.")
else if not mwritepropdef.is_intro then
modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot be set on redefinitions.")
else if not mclassdef.is_intro then
modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot be used in class refinements.")
else if atabstract == null then
modelbuilder.warning(atautoinit, "useless-autoinit", "Warning: superfluous `autoinit` on attribute.")
end
else if atabstract != null then
# By default, abstract attribute are not autoinit
noinit = true
end
end
# Build the attribute property
fun build_attribute_property(modelbuilder: ModelBuilder, mclassdef: MClassDef)
do
var mclass = mclassdef.mclass
var attribute_name = "_" + name
if not mclass.kind.need_init then
modelbuilder.error(self, "Error: attempt to define attribute `{name}` in the {mclass.kind} `{mclass}`.")
end
var mprop = new MAttribute(mclassdef, "_" + name, self.location, private_visibility)
var mpropdef = new MAttributeDef(mclassdef, mprop, self.location)
self.mpropdef = mpropdef
modelbuilder.mpropdef2npropdef[mpropdef] = self
end
# Build the read method property to get the value of the attribute
# Return `true` if the property was correctly created else return `false`.
# Warning the signature of the property is not set. This step is done by `build_signature`.
fun build_read_property(modelbuilder: ModelBuilder, mclassdef: MClassDef): Bool
do
var mclass = mclassdef.mclass
var readname = name
var mreadprop = modelbuilder.try_get_mproperty_by_name(self, mclassdef, readname).as(nullable MMethod)
if mreadprop == null then
var mvisibility = new_property_visibility(modelbuilder, mclassdef, self.n_visibility)
mreadprop = new MMethod(mclassdef, readname, self.location, mvisibility)
if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mreadprop) then
mreadprop.is_broken = true
return false
end
else
if mreadprop.is_broken then return false
if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, true, mreadprop) then return false
check_redef_property_visibility(modelbuilder, self.n_visibility, mreadprop)
end
mclassdef.mprop2npropdef[mreadprop] = self
var attr_mpropdef = mpropdef
if attr_mpropdef != null then
mreadprop.getter_for = attr_mpropdef.mproperty
attr_mpropdef.mproperty.getter = mreadprop
end
var mreadpropdef = new MMethodDef(mclassdef, mreadprop, self.location)
self.mreadpropdef = mreadpropdef
modelbuilder.mpropdef2npropdef[mreadpropdef] = self
set_doc(mreadpropdef, modelbuilder)
if mpropdef != null then mpropdef.mdoc = mreadpropdef.mdoc
return true
end
# Build the write method property to set the attribute value
# Return `true` if the property was correctly created else return `false`.
# Warning the signature of the property is not set.
fun build_write_property(modelbuilder: ModelBuilder, mclassdef: MClassDef, is_same_visibility: Bool): Bool
do
var mclass = mclassdef.mclass
var writename = name + "="
var atwritable = self.get_single_annotation("writable", modelbuilder)
if atwritable != null then
if not atwritable.n_args.is_empty then
writename = atwritable.arg_as_id(modelbuilder) or else writename
end
end
var mwriteprop = modelbuilder.try_get_mproperty_by_name(self, mclassdef, writename).as(nullable MMethod)
var nwkwredef: nullable Token = null
if atwritable != null then nwkwredef = atwritable.n_kwredef
if mwriteprop == null then
var mvisibility
if atwritable != null then
mvisibility = new_property_visibility(modelbuilder, mclassdef, atwritable.n_visibility)
else
mvisibility = mreadpropdef.mproperty.visibility
# By default, use protected visibility at most
if mvisibility > protected_visibility and not is_same_visibility then mvisibility = protected_visibility
end
mwriteprop = new MMethod(mclassdef, writename, self.location, mvisibility)
if not self.check_redef_keyword(modelbuilder, mclassdef, nwkwredef, false, mwriteprop) then
mwriteprop.is_broken = true
return false
end
mwriteprop.deprecation = mreadpropdef.mproperty.deprecation
else
if mwriteprop.is_broken then return false
if not self.check_redef_keyword(modelbuilder, mclassdef, nwkwredef or else n_kwredef, true, mwriteprop) then return false
if atwritable != null then
check_redef_property_visibility(modelbuilder, atwritable.n_visibility, mwriteprop)
end
end
mclassdef.mprop2npropdef[mwriteprop] = self
var attr_mpropdef = mpropdef
if attr_mpropdef != null then
mwriteprop.setter_for = attr_mpropdef.mproperty
attr_mpropdef.mproperty.setter = mwriteprop
end
var mwritepropdef = new MMethodDef(mclassdef, mwriteprop, self.location)
self.mwritepropdef = mwritepropdef
modelbuilder.mpropdef2npropdef[mwritepropdef] = self
mwritepropdef.mdoc = mreadpropdef.mdoc
return true
end
# Build the lazy attribute property
# Return `true` if the property was correctly created else return `false`.
fun build_lazy_property(modelbuilder: ModelBuilder, mclassdef: MClassDef): Bool
do
var mclass = mclassdef.mclass
var atlazy = self.get_single_annotation("lazy", modelbuilder)
var atlateinit = self.get_single_annotation("lateinit", modelbuilder)
if atlazy != null or atlateinit != null then
if atlazy != null and atlateinit != null then
modelbuilder.error(atlazy, "Error: `lazy` incompatible with `lateinit`.")
return false
end
if not has_value then
if atlazy != null then
modelbuilder.error(atlazy, "Error: `lazy` attributes need a value.")
else if atlateinit != null then
modelbuilder.error(atlateinit, "Error: `lateinit` attributes need a value.")
end
has_value = true
return false
end
create_lazy
end
return true
end
redef fun build_signature(modelbuilder)
do
var mreadpropdef = self.mreadpropdef
var mpropdef = self.mpropdef
if mreadpropdef == null then return # Error thus skipped
var mclassdef = mreadpropdef.mclassdef
var mmodule = mclassdef.mmodule
var mtype: nullable MType = null
var ntype = self.n_type
if ntype != null then
mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, ntype, true)
if mtype == null then return
end
var inherited_type: nullable MType = null
# Inherit the type from the getter (usually an abstract getter)
if not mreadpropdef.is_intro then
var msignature = mreadpropdef.mproperty.intro.msignature
if msignature == null then return # Error, thus skipped
inherited_type = msignature.return_mtype
if inherited_type != null then
# The inherited type is adapted to use the local formal types, if any.
inherited_type = inherited_type.resolve_for(mclassdef.mclass.mclass_type, mclassdef.bound_mtype, mmodule, false)
if mtype == null then mtype = inherited_type
end
end
var nexpr = self.n_expr
if mtype == null then
if nexpr != null then
mtype = infer_static_type(modelbuilder, nexpr, mclassdef, mmodule, mreadpropdef)
if mtype == null then return
end
else if ntype != null and inherited_type == mtype then
if nexpr isa ANewExpr then
var xmtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true)
if xmtype == mtype then
modelbuilder.advice(ntype, "useless-type", "Warning: useless type definition")
end
end
end
if mtype == null then
modelbuilder.error(self, "Error: untyped attribute `{mreadpropdef}`.")
return
end
self.mtype = mtype
if mpropdef != null then
mpropdef.static_mtype = mtype
end
build_read_signature
if self.mwritepropdef != null then build_write_signature
var mlazypropdef = self.mlazypropdef
if mlazypropdef != null then
mlazypropdef.static_mtype = mmodule.bool_type
end
check_repeated_types(modelbuilder)
end
# Build the read method signature
# `except`: mreadpropdef != null
# `expect`: mtype != null
fun build_read_signature
is
expect(mreadpropdef != null and mtype != null)
do
var msignature = new MSignature(new Array[MParameter], mtype)
mreadpropdef.msignature = msignature
end
# Build the write method signature
# `except`: mwritepropdef != null
# `expect`: mtype != null
fun build_write_signature
is
expect(mwritepropdef != null and mtype != null)
do
var mwritetype = mtype.as(not null)
if is_optional then
mwritetype = mwritetype.as_nullable
end
var mparameter = new MParameter(name, mwritetype, false)
var msignature = new MSignature([mparameter], null)
mwritepropdef.msignature = msignature
end
# Create a new setter for the attribute.
#
# `modelbuilder`: It's used to link the new `mwritepropdef` and `self`
# `visibility`: Is the setter has the same visibilty of the `mreadpropdef`.
# If `not is_same_visibility and mreadpropdef.mproperty.visibility > protected_visibility` the `mwritepropdef` visibility will be set to protected.
fun create_setter(modelbuilder: ModelBuilder, is_same_visibility: nullable Bool): AAttrPropdef
is
expect(mreadpropdef != null) # Use to define the visibility, the mclassdef and the doc of the `mwritepropdef`
do
if mwritepropdef != null then return self # Self already has a `mwritepropdef`
var same_visibility = false
if is_same_visibility != null then same_visibility = is_same_visibility
self.build_write_property(modelbuilder, mreadpropdef.mclassdef, same_visibility)
self.build_write_signature
return self
end
# Set the default `self` value
#
# `expr`: Represents the default value of the attribute. If `expr isa ABlockExpr` `self.n_block` will be set.
fun define_default(expr: AExpr): AAttrPropdef
do
self.has_value = true
if expr isa ABlockExpr then
self.n_block = expr
else
self.n_expr = expr
end
return self
end
# Set `self` as optional
fun define_as_optional: AAttrPropdef
is
expect(has_value)
do
is_optional = true
return self
end
# Create the lazy attribute.
#
# see `mlazypropdef` for more information about this property.
fun create_lazy: AAttrPropdef
is
expect(has_value and mpropdef != null) # The only way to get a null `mpropdef` is when the attribute is defined as `abstract`. But if the attribute has a value, it cannot be abstract.
do
if self.mlazypropdef != null then return self # Self already has a `mlazypropdef`
is_lazy = true
var mlazyprop = new MAttribute(mpropdef.mclassdef, "lazy _" + name, self.location, none_visibility)
mlazyprop.is_fictive = true
var mlazypropdef = new MAttributeDef(mpropdef.mclassdef, mlazyprop, self.location)
mlazypropdef.is_fictive = true
self.mlazypropdef = mlazypropdef
return self
end
# Detect the static type from the value assigned to the attribute `self`
#
# Return the static type if it can be safely inferred.
private fun infer_static_type(modelbuilder: ModelBuilder, nexpr: AExpr,
mclassdef: MClassDef, mmodule: MModule, mreadpropdef: MPropDef): nullable MType
do
var mtype = null
if nexpr isa ANewExpr then
mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true)
else if nexpr isa AAsCastExpr then
mtype = modelbuilder.resolve_mtype_unchecked(mclassdef, nexpr.n_type, true)
else if nexpr isa AIntegerExpr then
var cla: nullable MClass = null
if nexpr.value isa Int then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int")
else if nexpr.value isa Byte then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Byte")
else if nexpr.value isa Int8 then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int8")
else if nexpr.value isa Int16 then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int16")
else if nexpr.value isa UInt16 then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "UInt16")
else if nexpr.value isa Int32 then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int32")
else if nexpr.value isa UInt32 then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "UInt32")
else
# Should not happen, and should be updated as new types are added
abort
end
if cla != null then mtype = cla.mclass_type
else if nexpr isa AFloatExpr then
var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Float")
if cla != null then mtype = cla.mclass_type
else if nexpr isa ACharExpr then
var cla: nullable MClass
if nexpr.is_code_point then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Int")
else
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Char")
end
if cla != null then mtype = cla.mclass_type
else if nexpr isa ABoolExpr then
var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Bool")
if cla != null then mtype = cla.mclass_type
else if nexpr isa ASuperstringExpr then
var cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "String")
if cla != null then mtype = cla.mclass_type
else if nexpr isa AStringFormExpr then
var cla: nullable MClass
if nexpr.is_bytestring then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Bytes")
else if nexpr.is_re then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "Regex")
else if nexpr.is_string then
cla = modelbuilder.try_get_mclass_by_name(nexpr, mmodule, "String")
else
abort
end
if cla != null then mtype = cla.mclass_type
else if nexpr isa AArrayExpr and nexpr.n_type == null and nexpr.n_exprs.not_empty then
# Non-empty arrays without an explicit type
var item_mtypes = new Set[MType]
var fails = false
for node in nexpr.n_exprs do
var item_mtype = infer_static_type(modelbuilder, node, mclassdef, mmodule, mreadpropdef)
if item_mtype == null then
fails = true
else
item_mtypes.add item_mtype
end
end
if fails then return null # Failed to infer some types
if item_mtypes.length > 1 then
modelbuilder.error(self, "Type Error: ambiguous array type {item_mtypes.join(" ")}")
end
mtype = mmodule.array_type(item_mtypes.first)
else if nexpr isa AUminusExpr and (nexpr.n_expr isa AIntegerExpr or nexpr.n_expr isa AFloatExpr) then
# The Int and Float unary - is defined in `kernel`, so this may
# result in an invalid behavior when using a custom kernel.
# A workaround is to declare the attribute static type.
# This is still very useful, especially to novice programmers.
mtype = infer_static_type(modelbuilder, nexpr.n_expr, mclassdef, mmodule, mreadpropdef)
else if nexpr isa AOnceExpr then
mtype = infer_static_type(modelbuilder, nexpr.n_expr, mclassdef, mmodule, mreadpropdef)
else
modelbuilder.error(self, "Error: untyped attribute `{mreadpropdef}`. Implicit typing allowed only for literals and new.")
end
return mtype
end
redef fun check_signature(modelbuilder)
do
var mpropdef = self.mpropdef
if mpropdef == null then return # Error thus skipped
var ntype = self.n_type
var mtype = self.mtype
if mtype == null then return # Error thus skipped
var mclassdef = mpropdef.mclassdef
var mmodule = mclassdef.mmodule
# Check types
if ntype != null then
if modelbuilder.resolve_mtype(mclassdef, ntype) == null then return
end
var nexpr = n_expr
if nexpr isa ANewExpr then
if modelbuilder.resolve_mtype(mclassdef, nexpr.n_type) == null then return
end
# Lookup for signature in the precursor
# FIXME all precursors should be considered
if not mpropdef.is_intro then
var precursor_type = mpropdef.mproperty.intro.static_mtype
if precursor_type == null then return
if mtype != precursor_type then
modelbuilder.error(ntype.as(not null), "Redef Error: expected `{precursor_type}` type as a bound; got `{mtype}`.")
return
end
end
# Check getter and setter
var meth = self.mreadpropdef
if meth != null then
self.check_method_signature(modelbuilder, meth)
var node: nullable ANode = ntype
if node == null then node = self
modelbuilder.check_visibility(node, mtype, meth)
end
meth = self.mwritepropdef
if meth != null then
self.check_method_signature(modelbuilder, meth)
var node: nullable ANode = ntype
if node == null then node = self
modelbuilder.check_visibility(node, mtype, meth)
end
end
private fun check_method_signature(modelbuilder: ModelBuilder, mpropdef: MMethodDef)
do
var mclassdef = mpropdef.mclassdef
var mmodule = mclassdef.mmodule
var nsig = self.n_type
var mysignature = mpropdef.msignature
if mysignature == null then return # Error thus skiped
# Lookup for signature in the precursor
# FIXME all precursors should be considered
if not mpropdef.is_intro then
var msignature = mpropdef.mproperty.intro.msignature
if msignature == null then return
if mysignature.arity != msignature.arity then
var node: ANode
if nsig != null then node = nsig else node = self
modelbuilder.error(node, "Redef Error: expected {msignature.arity} parameter(s) for `{mpropdef.mproperty.name}{msignature}`; got {mysignature.arity}. See introduction at `{mpropdef.mproperty.full_name}`.")
return
end
var precursor_ret_type = msignature.return_mtype
var ret_type = mysignature.return_mtype
if ret_type != null and precursor_ret_type == null then
var node: ANode
if nsig != null then node = nsig else node = self
modelbuilder.error(node, "Redef Error: `{mpropdef.mproperty}` is a procedure, not a function.")
return
end
if mysignature.arity > 0 then
# Check parameters types
for i in [0..mysignature.arity[ do
var myt = mysignature.mparameters[i].mtype
var prt = msignature.mparameters[i].mtype
var node: ANode
if nsig != null then node = nsig else node = self
if not modelbuilder.check_sametype(node, mmodule, mclassdef.bound_mtype, myt, prt) then
modelbuilder.error(node, "Redef Error: expected `{prt}` type for parameter `{mysignature.mparameters[i].name}'; got `{myt}`.")
end
end
end
if precursor_ret_type != null then
var node: ANode
if nsig != null then node = nsig else node = self
if ret_type == null then
# Inherit the return type
ret_type = precursor_ret_type
else if not modelbuilder.check_subtype(node, mmodule, mclassdef.bound_mtype, ret_type, precursor_ret_type) then
modelbuilder.error(node, "Redef Error: expected `{precursor_ret_type}` return type; got `{ret_type}`.")
end
end
end
end
# Type is useless if the attribute type is the same thant the intro.
redef fun check_repeated_types(modelbuilder) do
var mreadpropdef = self.mreadpropdef
if mreadpropdef == null then return
if mreadpropdef.is_intro or n_type == null then return
# get intro
var intro = mreadpropdef.mproperty.intro
var n_intro = modelbuilder.mpropdef2npropdef.get_or_null(intro)
if n_intro == null then return
# get intro type
var ntype = null
if n_intro isa AMethPropdef then
ntype = n_intro.n_signature.ret_type
else if n_intro isa AAttrPropdef and n_intro.n_type != null then
ntype = n_intro.n_type.mtype
end
# check
if ntype == null or ntype != n_type.mtype or mpropdef == null then return
modelbuilder.advice(n_type, "useless-signature", "Warning: useless type repetition on redefined attribute `{mpropdef.name}`")
end
end
src/modelize/modelize_property.nit:1175,1--1794,3
redef class AAttrPropdef
redef fun accept_pretty_printer(v) do
super
v.visit n_kwvar
v.adds
v.visit n_id2
if n_type != null then
v.consume ":"
v.adds
v.visit n_type
end
if n_expr != null then
v.adds
v.consume "="
v.adds
v.visit n_expr
end
var annot_inline = visit_annotations(v, n_annotations)
visit_block(v, n_block, annot_inline)
v.finish_line
v.addn
end
redef fun first_token do
if n_doc != null then return n_doc.first_token
if not n_visibility isa APublicVisibility then return n_visibility.first_token
if n_kwredef != null then return n_kwredef
return n_kwvar
end
redef fun is_inlinable do return true
end
src/pretty.nit:907,1--941,3
redef class AAttrPropdef
# Name of this attribute in the serialized format
private var serialize_name: String = name is lazy
end
src/frontend/serialization_model_phase.nit:269,1--272,3
redef class AAttrPropdef
redef fun do_typing(modelbuilder: ModelBuilder)
do
if not has_value then return
var mpropdef = self.mreadpropdef
if mpropdef == null or mpropdef.msignature == null then return # skip error
var v = new TypeVisitor(modelbuilder, mpropdef)
self.selfvariable = v.selfvariable
var nexpr = self.n_expr
if nexpr != null then
var mtype = self.mtype
v.visit_expr_subtype(nexpr, mtype)
end
var nblock = self.n_block
if nblock != null then
v.visit_stmt(nblock)
if not nblock.after_flow_context.is_unreachable then
# We reach the end of the init without having a return, it is bad
v.error(self, "Error: reached end of block; expected `return`.")
end
end
end
end
src/semantize/typing.nit:961,1--986,3
redef class AAttrPropdef
# Create a new `AAttrPropdef`
# Note: By default if the `AVisibility` is not given the visibility is set to public
private init make(name: String,
n_type: nullable AType,
n_visibility: nullable AVisibility,
initial_value: nullable AExpr,
n_block: nullable AExpr,
m_attributedef: nullable MAttributeDef,
m_setterdef: nullable MMethodDef,
m_getterdef: nullable MMethodDef)
do
# Set the model type
if n_type != null then mtype = n_type.mtype
# Define the visibility default is public
if n_visibility == null then n_visibility = new APublicVisibility
init_aattrpropdef(null, null, n_visibility, new TKwvar, new TId, n_type, null, initial_value, null, null , n_block, null)
# Set the name of the attribute
_n_id2.text = name
_mpropdef = m_attributedef
_mreadpropdef = m_getterdef
_mwritepropdef = m_setterdef
if initial_value != null or n_block != null then has_value = true
if m_attributedef != null then self.location = m_attributedef.location
end
end
src/astbuilder.nit:335,1--361,3
redef class AAttrPropdef
redef fun call(v, mpropdef, args)
do
var recv = args.first
assert recv isa MutableInstance
var attr = self.mpropdef.mproperty
if mpropdef == mreadpropdef then
assert args.length == 1
if not is_lazy or v.isset_attribute(attr, recv) then return v.read_attribute(attr, recv)
var f = v.new_frame(self, mpropdef, args)
return evaluate_expr(v, recv, f)
else if mpropdef == mwritepropdef then
assert args.length == 2
var arg = args[1]
if is_optional and arg.is_null then
var f = v.new_frame(self, mpropdef, args)
arg = evaluate_expr(v, recv, f)
end
v.write_attribute(attr, recv, arg)
return null
else
abort
end
end
# Evaluate and set the default value of the attribute in `recv`
private fun init_expr(v: NaiveInterpreter, recv: Instance)
do
if is_lazy or is_optional then return
if has_value then
var f = v.new_frame(self, mreadpropdef.as(not null), [recv])
evaluate_expr(v, recv, f)
return
end
var mpropdef = self.mpropdef
if mpropdef == null then return
var mtype = self.mtype.as(not null)
mtype = mtype.anchor_to(v.mainmodule, recv.mtype.as(MClassType))
if mtype isa MNullableType then
v.write_attribute(self.mpropdef.mproperty, recv, v.null_instance)
end
end
private fun evaluate_expr(v: NaiveInterpreter, recv: Instance, f: Frame): Instance
do
assert recv isa MutableInstance
v.frames.unshift(f)
var val
var nexpr = self.n_expr
var nblock = self.n_block
if nexpr != null then
val = v.expr(nexpr)
else if nblock != null then
v.stmt(nblock)
assert v.escapemark == return_mark
val = v.escapevalue
v.escapemark = null
else
abort
end
assert val != null
v.frames.shift
assert not v.is_escaping
v.write_attribute(self.mpropdef.mproperty, recv, val)
return val
end
end
src/interpreter/naive_interpreter.nit:1555,1--1624,3
redef class AAttrPropdef
redef fun can_inline: Bool do return not is_lazy
redef fun compile_to_c(v, mpropdef, arguments)
do
if mpropdef == mreadpropdef then
assert arguments.length == 1
var recv = arguments.first
var res
if is_lazy then
var set
var ret = self.mtype
var useiset = not ret.is_c_primitive and not ret isa MNullableType
var guard = self.mlazypropdef.mproperty
if useiset then
set = v.isset_attribute(self.mpropdef.mproperty, recv)
else
set = v.read_attribute(guard, recv)
end
v.add("if(likely({set})) \{")
res = v.read_attribute(self.mpropdef.mproperty, recv)
v.add("\} else \{")
var value = evaluate_expr(v, recv)
v.assign(res, value)
if not useiset then
var true_v = v.bool_instance(true)
v.write_attribute(guard, arguments.first, true_v)
end
v.add("\}")
else
res = v.read_attribute(self.mpropdef.mproperty, arguments.first)
end
v.assign(v.frame.returnvar.as(not null), res)
else if mpropdef == mwritepropdef then
assert arguments.length == 2
var recv = arguments.first
var arg = arguments[1]
if is_optional and v.maybe_null(arg) then
var value = v.new_var(self.mpropdef.static_mtype.as(not null))
v.add("if ({arg} == NULL) \{")
v.assign(value, evaluate_expr(v, recv))
v.add("\} else \{")
v.assign(value, arg)
v.add("\}")
arg = value
end
v.write_attribute(self.mpropdef.mproperty, arguments.first, arg)
if is_lazy then
var ret = self.mtype
var useiset = not ret.is_c_primitive and not ret isa MNullableType
if not useiset then
v.write_attribute(self.mlazypropdef.mproperty, arguments.first, v.bool_instance(true))
end
end
else
abort
end
end
fun init_expr(v: AbstractCompilerVisitor, recv: RuntimeVariable)
do
if has_value and not is_lazy and not is_optional and not n_expr isa ANullExpr then evaluate_expr(v, recv)
end
# Evaluate, store and return the default value of the attribute
private fun evaluate_expr(v: AbstractCompilerVisitor, recv: RuntimeVariable): RuntimeVariable
do
var oldnode = v.current_node
v.current_node = self
var old_frame = v.frame
var frame = new StaticFrame(v, self.mreadpropdef.as(not null), recv.mcasttype.undecorate.as(MClassType), [recv])
v.frame = frame
var value
var mtype = self.mtype
assert mtype != null
var nexpr = self.n_expr
var nblock = self.n_block
if nexpr != null then
value = v.expr(nexpr, mtype)
else if nblock != null then
value = v.new_var(mtype)
frame.returnvar = value
frame.returnlabel = v.get_name("RET_LABEL")
v.add("\{")
v.stmt(nblock)
v.add("{frame.returnlabel.as(not null)}:(void)0;")
v.add("\}")
else
abort
end
v.write_attribute(self.mpropdef.mproperty, recv, value)
v.frame = old_frame
v.current_node = oldnode
return value
end
fun check_expr(v: AbstractCompilerVisitor, recv: RuntimeVariable)
do
var nexpr = self.n_expr
if nexpr != null then return
var oldnode = v.current_node
v.current_node = self
var old_frame = v.frame
var frame = new StaticFrame(v, self.mpropdef.as(not null), recv.mtype.as(MClassType), [recv])
v.frame = frame
# Force read to check the initialization
v.read_attribute(self.mpropdef.mproperty, recv)
v.frame = old_frame
v.current_node = oldnode
end
end
src/compiler/abstract_compiler.nit:3561,1--3679,3
redef class AAttrPropdef
redef fun init_expr(v, recv)
do
super
if is_lazy and v.compiler.modelbuilder.toolcontext.opt_no_union_attribute.value then
var guard = self.mlazypropdef.mproperty
v.write_attribute(guard, recv, v.bool_instance(false))
end
end
end
src/compiler/separate_compiler.nit:2666,1--2675,3
redef class AAttrPropdef
redef fun generate_basic_blocks(ssa: SSA)
do
basic_block = new BasicBlock
basic_block.first = self
basic_block.last = self
# Add the return variable
variables.add(returnvar)
# Add the self variable
if self.selfvariable != null then variables.add(selfvariable.as(not null))
# Recursively goes into the nodes
if n_block != null then
n_block.generate_basic_blocks(ssa, basic_block.as(not null))
is_generated = true
end
end
end
src/ssa.nit:471,1--490,3
redef class AAttrPropdef
# Assign a position in the environment to each local variable
# *`vm` The current VirtualMachine
redef fun numbering_variables(vm: VirtualMachine)
do
# The position in the environment
var position = 0
# The `self` variable has the first position
if self.selfvariable != null then
self.selfvariable.position = position
position += 1
end
# Recursively go into the AST nodes to number all local variables
if n_block != null then
position = vm.numbering(self.n_block, position)
end
is_numbering = true
# The size of the environment to create to execute a call to this method
environment_size = position
end
end
src/vm/variables_numbering.nit:152,1--176,3
redef class AAttrPropdef
redef fun compile_to_java(v, mpropdef, arguments) do
v.current_node = self
if mpropdef == mreadpropdef then
compile_getter(v, mpropdef, arguments)
else if mpropdef == mwritepropdef then
compile_setter(v, mpropdef, arguments)
else
abort
end
v.current_node = null
end
# Compile the setter method
private fun compile_setter(v: JavaCompilerVisitor, mpropdef: MPropDef, arguments: Array[RuntimeVariable]) do
var mtype = v.compiler.mainmodule.object_type
var recv = arguments.first
var val = v.new_expr("args[1]", mtype)
v.write_attribute(self.mpropdef.as(not null).mproperty, recv, val)
v.ret v.null_instance
end
# Compile the getter method
private fun compile_getter(v: JavaCompilerVisitor, mpropdef: MPropDef, arguments: Array[RuntimeVariable]) do
var recv = arguments.first
v.ret v.read_attribute(self.mpropdef.as(not null).mproperty, recv)
end
private fun init_expr(v: JavaCompilerVisitor, recv: RuntimeVariable) do
if has_value and not is_lazy and not n_expr isa ANullExpr then evaluate_expr(v, recv)
end
# Evaluate, store and return the default value of the attribute
private fun evaluate_expr(v: JavaCompilerVisitor, recv: RuntimeVariable): RuntimeVariable do
var old = v.frame
var frame = new JavaStaticFrame(v, self.mreadpropdef.as(not null), recv.mcasttype.undecorate.as(MClassType), [recv])
v.frame = frame
var value
var mtype = self.mtype
assert mtype != null
var nexpr = self.n_expr
var nblock = self.n_block
if nexpr != null then
value = v.expr(nexpr, mtype)
else if nblock != null then
value = v.new_var(mtype)
frame.returnvar = value
frame.returnlabel = v.get_name("RET_LABEL")
v.add("{frame.returnlabel.as(not null)}: \{")
v.stmt(nblock)
v.add("\}")
else
abort
end
v.write_attribute(self.mpropdef.as(not null).mproperty, recv, value)
v.frame = old
return value
end
end
src/compiler/java_compiler.nit:1840,1--1901,3
redef class AAttrPropdef
redef fun decorate_tag(v, res, token)
do
if not token isa TId then return null
res.add_class("nc_def")
var mpd: nullable MPropDef
mpd = mreadpropdef
if mpd == null then mpd = mpropdef
if mpd == null then return null
return mpd.infobox(v)
end
end
src/htmlight.nit:964,1--975,3