Skip to content

Commit 0bf1b73

Browse files
committed
modelize_property: Split model build of AAttrPropdef
Split the build method of AAttrPropdef Signed-off-by: Florian Deljarry <[email protected]>
1 parent 4523ec4 commit 0bf1b73

File tree

2 files changed

+159
-99
lines changed

2 files changed

+159
-99
lines changed

src/frontend/serialization_model_phase.nit

-2
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,6 @@ redef init from_deserializer(v) do abort"""
267267
end
268268

269269
redef class AAttrPropdef
270-
private fun name: String do return n_id2.text
271-
272270
# Name of this attribute in the serialized format
273271
private var serialize_name: String = name is lazy
274272
end

src/modelize/modelize_property.nit

+159-97
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,10 @@ redef class AAttrPropdef
11811181
# Could be through `n_expr`, `n_block` or `is_lazy`
11821182
var has_value = false
11831183

1184+
# The name of the attribute
1185+
# Note: The name of the attribute is in reality the name of the mreadpropdef
1186+
var name: String = n_id2.text is lazy
1187+
11841188
# The guard associated to a lazy attribute.
11851189
# Because some engines does not have a working `isset`,
11861190
# this additional attribute is used to guard the lazy initialization.
@@ -1195,48 +1199,14 @@ redef class AAttrPropdef
11951199
redef fun build_property(modelbuilder, mclassdef)
11961200
do
11971201
var mclass = mclassdef.mclass
1198-
var nid2 = n_id2
1199-
var name = nid2.text
12001202

12011203
var atabstract = self.get_single_annotation("abstract", modelbuilder)
1202-
if atabstract == null then
1203-
if not mclass.kind.need_init then
1204-
modelbuilder.error(self, "Error: attempt to define attribute `{name}` in the {mclass.kind} `{mclass}`.")
1205-
end
12061204

1207-
var mprop = new MAttribute(mclassdef, "_" + name, self.location, private_visibility)
1208-
var mpropdef = new MAttributeDef(mclassdef, mprop, self.location)
1209-
self.mpropdef = mpropdef
1210-
modelbuilder.mpropdef2npropdef[mpropdef] = self
1211-
end
1205+
if atabstract == null then build_attribute_property(modelbuilder, mclassdef)
12121206

1213-
var readname = name
1214-
var mreadprop = modelbuilder.try_get_mproperty_by_name(nid2, mclassdef, readname).as(nullable MMethod)
1215-
if mreadprop == null then
1216-
var mvisibility = new_property_visibility(modelbuilder, mclassdef, self.n_visibility)
1217-
mreadprop = new MMethod(mclassdef, readname, self.location, mvisibility)
1218-
if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mreadprop) then
1219-
mreadprop.is_broken = true
1220-
return
1221-
end
1222-
else
1223-
if mreadprop.is_broken then return
1224-
if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, true, mreadprop) then return
1225-
check_redef_property_visibility(modelbuilder, self.n_visibility, mreadprop)
1226-
end
1227-
mclassdef.mprop2npropdef[mreadprop] = self
1228-
1229-
var attr_mpropdef = mpropdef
1230-
if attr_mpropdef != null then
1231-
mreadprop.getter_for = attr_mpropdef.mproperty
1232-
attr_mpropdef.mproperty.getter = mreadprop
1233-
end
1207+
# Construction of the read property. If it's not correctly built just return.
1208+
if not build_read_property(modelbuilder, mclassdef) then return
12341209

1235-
var mreadpropdef = new MMethodDef(mclassdef, mreadprop, self.location)
1236-
self.mreadpropdef = mreadpropdef
1237-
modelbuilder.mpropdef2npropdef[mreadpropdef] = self
1238-
set_doc(mreadpropdef, modelbuilder)
1239-
if mpropdef != null then mpropdef.mdoc = mreadpropdef.mdoc
12401210
if atabstract != null then mreadpropdef.is_abstract = true
12411211

12421212
has_value = n_expr != null or n_block != null
@@ -1259,29 +1229,8 @@ redef class AAttrPropdef
12591229
end
12601230
end
12611231

1262-
var atlazy = self.get_single_annotation("lazy", modelbuilder)
1263-
var atlateinit = self.get_single_annotation("lateinit", modelbuilder)
1264-
if atlazy != null or atlateinit != null then
1265-
if atlazy != null and atlateinit != null then
1266-
modelbuilder.error(atlazy, "Error: `lazy` incompatible with `lateinit`.")
1267-
return
1268-
end
1269-
if not has_value then
1270-
if atlazy != null then
1271-
modelbuilder.error(atlazy, "Error: `lazy` attributes need a value.")
1272-
else if atlateinit != null then
1273-
modelbuilder.error(atlateinit, "Error: `lateinit` attributes need a value.")
1274-
end
1275-
has_value = true
1276-
return
1277-
end
1278-
is_lazy = true
1279-
var mlazyprop = new MAttribute(mclassdef, "lazy _" + name, self.location, none_visibility)
1280-
mlazyprop.is_fictive = true
1281-
var mlazypropdef = new MAttributeDef(mclassdef, mlazyprop, self.location)
1282-
mlazypropdef.is_fictive = true
1283-
self.mlazypropdef = mlazypropdef
1284-
end
1232+
# Construction of the read property. If it's not correctly built just return.
1233+
if not build_lazy_property(modelbuilder, mclassdef) then return
12851234

12861235
var atoptional = self.get_single_annotation("optional", modelbuilder)
12871236
if atoptional != null then
@@ -1304,40 +1253,123 @@ redef class AAttrPropdef
13041253
modelbuilder.advice(self, "attr-in-refinement", "Warning: attributes in refinement need a value or `noautoinit`.")
13051254
end
13061255

1256+
# Construction of the read property. If it's not correctly built just return.
1257+
if not build_write_property(modelbuilder, mclassdef, false) then return
1258+
1259+
if atabstract != null then mwritepropdef.is_abstract = true
1260+
1261+
var atautoinit = self.get_single_annotation("autoinit", modelbuilder)
1262+
if atautoinit != null then
1263+
if has_value then
1264+
modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot have an initial value.")
1265+
else if not mwritepropdef.is_intro then
1266+
modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot be set on redefinitions.")
1267+
else if not mclassdef.is_intro then
1268+
modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot be used in class refinements.")
1269+
else if atabstract == null then
1270+
modelbuilder.warning(atautoinit, "useless-autoinit", "Warning: superfluous `autoinit` on attribute.")
1271+
end
1272+
else if atabstract != null then
1273+
# By default, abstract attribute are not autoinit
1274+
noinit = true
1275+
end
1276+
end
1277+
1278+
# Build the attribute property
1279+
fun build_attribute_property(modelbuilder: ModelBuilder, mclassdef: MClassDef)
1280+
do
1281+
var mclass = mclassdef.mclass
1282+
var attribute_name = "_" + name
1283+
1284+
if not mclass.kind.need_init then
1285+
modelbuilder.error(self, "Error: attempt to define attribute `{name}` in the {mclass.kind} `{mclass}`.")
1286+
end
1287+
var mprop = new MAttribute(mclassdef, "_" + name, self.location, private_visibility)
1288+
var mpropdef = new MAttributeDef(mclassdef, mprop, self.location)
1289+
self.mpropdef = mpropdef
1290+
modelbuilder.mpropdef2npropdef[mpropdef] = self
1291+
end
1292+
1293+
# Build the read method property to get the value of the attribute
1294+
# Return `true` if the property was correctly created else return `false`.
1295+
# Warning the signature of the property is not set. This step is done by `build_signature`.
1296+
fun build_read_property(modelbuilder: ModelBuilder, mclassdef: MClassDef): Bool
1297+
do
1298+
var mclass = mclassdef.mclass
1299+
1300+
var readname = name
1301+
var mreadprop = modelbuilder.try_get_mproperty_by_name(self, mclassdef, readname).as(nullable MMethod)
1302+
if mreadprop == null then
1303+
var mvisibility = new_property_visibility(modelbuilder, mclassdef, self.n_visibility)
1304+
mreadprop = new MMethod(mclassdef, readname, self.location, mvisibility)
1305+
if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, false, mreadprop) then
1306+
mreadprop.is_broken = true
1307+
return false
1308+
end
1309+
else
1310+
if mreadprop.is_broken then return false
1311+
if not self.check_redef_keyword(modelbuilder, mclassdef, n_kwredef, true, mreadprop) then return false
1312+
check_redef_property_visibility(modelbuilder, self.n_visibility, mreadprop)
1313+
end
1314+
mclassdef.mprop2npropdef[mreadprop] = self
1315+
1316+
var attr_mpropdef = mpropdef
1317+
if attr_mpropdef != null then
1318+
mreadprop.getter_for = attr_mpropdef.mproperty
1319+
attr_mpropdef.mproperty.getter = mreadprop
1320+
end
1321+
1322+
var mreadpropdef = new MMethodDef(mclassdef, mreadprop, self.location)
1323+
self.mreadpropdef = mreadpropdef
1324+
modelbuilder.mpropdef2npropdef[mreadpropdef] = self
1325+
set_doc(mreadpropdef, modelbuilder)
1326+
if mpropdef != null then mpropdef.mdoc = mreadpropdef.mdoc
1327+
1328+
return true
1329+
end
1330+
1331+
# Build the write method property to set the attribute value
1332+
# Return `true` if the property was correctly created else return `false`.
1333+
# Warning the signature of the property is not set.
1334+
fun build_write_property(modelbuilder: ModelBuilder, mclassdef: MClassDef, is_same_visibility: Bool): Bool
1335+
do
1336+
var mclass = mclassdef.mclass
1337+
13071338
var writename = name + "="
13081339
var atwritable = self.get_single_annotation("writable", modelbuilder)
13091340
if atwritable != null then
13101341
if not atwritable.n_args.is_empty then
13111342
writename = atwritable.arg_as_id(modelbuilder) or else writename
13121343
end
13131344
end
1314-
var mwriteprop = modelbuilder.try_get_mproperty_by_name(nid2, mclassdef, writename).as(nullable MMethod)
1345+
var mwriteprop = modelbuilder.try_get_mproperty_by_name(self, mclassdef, writename).as(nullable MMethod)
13151346
var nwkwredef: nullable Token = null
13161347
if atwritable != null then nwkwredef = atwritable.n_kwredef
13171348
if mwriteprop == null then
13181349
var mvisibility
13191350
if atwritable != null then
13201351
mvisibility = new_property_visibility(modelbuilder, mclassdef, atwritable.n_visibility)
13211352
else
1322-
mvisibility = mreadprop.visibility
1353+
mvisibility = mreadpropdef.mproperty.visibility
13231354
# By default, use protected visibility at most
1324-
if mvisibility > protected_visibility then mvisibility = protected_visibility
1355+
if mvisibility > protected_visibility and not is_same_visibility then mvisibility = protected_visibility
13251356
end
13261357
mwriteprop = new MMethod(mclassdef, writename, self.location, mvisibility)
13271358
if not self.check_redef_keyword(modelbuilder, mclassdef, nwkwredef, false, mwriteprop) then
13281359
mwriteprop.is_broken = true
1329-
return
1360+
return false
13301361
end
1331-
mwriteprop.deprecation = mreadprop.deprecation
1362+
mwriteprop.deprecation = mreadpropdef.mproperty.deprecation
13321363
else
1333-
if mwriteprop.is_broken then return
1334-
if not self.check_redef_keyword(modelbuilder, mclassdef, nwkwredef or else n_kwredef, true, mwriteprop) then return
1364+
if mwriteprop.is_broken then return false
1365+
if not self.check_redef_keyword(modelbuilder, mclassdef, nwkwredef or else n_kwredef, true, mwriteprop) then return false
13351366
if atwritable != null then
13361367
check_redef_property_visibility(modelbuilder, atwritable.n_visibility, mwriteprop)
13371368
end
13381369
end
13391370
mclassdef.mprop2npropdef[mwriteprop] = self
13401371

1372+
var attr_mpropdef = mpropdef
13411373
if attr_mpropdef != null then
13421374
mwriteprop.setter_for = attr_mpropdef.mproperty
13431375
attr_mpropdef.mproperty.setter = mwriteprop
@@ -1347,23 +1379,40 @@ redef class AAttrPropdef
13471379
self.mwritepropdef = mwritepropdef
13481380
modelbuilder.mpropdef2npropdef[mwritepropdef] = self
13491381
mwritepropdef.mdoc = mreadpropdef.mdoc
1350-
if atabstract != null then mwritepropdef.is_abstract = true
13511382

1352-
var atautoinit = self.get_single_annotation("autoinit", modelbuilder)
1353-
if atautoinit != null then
1354-
if has_value then
1355-
modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot have an initial value.")
1356-
else if not mwritepropdef.is_intro then
1357-
modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot be set on redefinitions.")
1358-
else if not mclassdef.is_intro then
1359-
modelbuilder.error(atautoinit, "Error: `autoinit` attributes cannot be used in class refinements.")
1360-
else if atabstract == null then
1361-
modelbuilder.warning(atautoinit, "useless-autoinit", "Warning: superfluous `autoinit` on attribute.")
1383+
return true
1384+
end
1385+
1386+
# Build the lazy attribute property
1387+
# Return `true` if the property was correctly created else return `false`.
1388+
fun build_lazy_property(modelbuilder: ModelBuilder, mclassdef: MClassDef): Bool
1389+
do
1390+
var mclass = mclassdef.mclass
1391+
1392+
var atlazy = self.get_single_annotation("lazy", modelbuilder)
1393+
var atlateinit = self.get_single_annotation("lateinit", modelbuilder)
1394+
if atlazy != null or atlateinit != null then
1395+
if atlazy != null and atlateinit != null then
1396+
modelbuilder.error(atlazy, "Error: `lazy` incompatible with `lateinit`.")
1397+
return false
13621398
end
1363-
else if atabstract != null then
1364-
# By default, abstract attribute are not autoinit
1365-
noinit = true
1399+
if not has_value then
1400+
if atlazy != null then
1401+
modelbuilder.error(atlazy, "Error: `lazy` attributes need a value.")
1402+
else if atlateinit != null then
1403+
modelbuilder.error(atlateinit, "Error: `lateinit` attributes need a value.")
1404+
end
1405+
has_value = true
1406+
return false
1407+
end
1408+
is_lazy = true
1409+
var mlazyprop = new MAttribute(mclassdef, "lazy _" + name, self.location, none_visibility)
1410+
mlazyprop.is_fictive = true
1411+
var mlazypropdef = new MAttributeDef(mclassdef, mlazyprop, self.location)
1412+
mlazypropdef.is_fictive = true
1413+
self.mlazypropdef = mlazypropdef
13661414
end
1415+
return true
13671416
end
13681417

13691418
redef fun build_signature(modelbuilder)
@@ -1421,23 +1470,9 @@ redef class AAttrPropdef
14211470
mpropdef.static_mtype = mtype
14221471
end
14231472

1424-
do
1425-
var msignature = new MSignature(new Array[MParameter], mtype)
1426-
mreadpropdef.msignature = msignature
1427-
end
1473+
build_read_signature
14281474

1429-
var mwritepropdef = self.mwritepropdef
1430-
if mwritepropdef != null then
1431-
var mwritetype = mtype
1432-
if is_optional then
1433-
mwritetype = mwritetype.as_nullable
1434-
end
1435-
var name: String
1436-
name = n_id2.text
1437-
var mparameter = new MParameter(name, mwritetype, false)
1438-
var msignature = new MSignature([mparameter], null)
1439-
mwritepropdef.msignature = msignature
1440-
end
1475+
if self.mwritepropdef != null then build_write_signature
14411476

14421477
var mlazypropdef = self.mlazypropdef
14431478
if mlazypropdef != null then
@@ -1446,6 +1481,33 @@ redef class AAttrPropdef
14461481
check_repeated_types(modelbuilder)
14471482
end
14481483

1484+
# Build the read method signature
1485+
# `except`: mreadpropdef != null
1486+
# `expect`: mtype != null
1487+
fun build_read_signature
1488+
is
1489+
expect(mreadpropdef != null and mtype != null)
1490+
do
1491+
var msignature = new MSignature(new Array[MParameter], mtype)
1492+
mreadpropdef.msignature = msignature
1493+
end
1494+
1495+
# Build the write method signature
1496+
# `except`: mwritepropdef != null
1497+
# `expect`: mtype != null
1498+
fun build_write_signature
1499+
is
1500+
expect(mwritepropdef != null and mtype != null)
1501+
do
1502+
var mwritetype = mtype.as(not null)
1503+
if is_optional then
1504+
mwritetype = mwritetype.as_nullable
1505+
end
1506+
var mparameter = new MParameter(name, mwritetype, false)
1507+
var msignature = new MSignature([mparameter], null)
1508+
mwritepropdef.msignature = msignature
1509+
end
1510+
14491511
# Detect the static type from the value assigned to the attribute `self`
14501512
#
14511513
# Return the static type if it can be safely inferred.

0 commit comments

Comments
 (0)