Skip to content

Commit 3c92d1e

Browse files
committed
Merge: modelize_property: Split the build_property method of AAttrPropdef
This pr split the `build property` method into several methods. The objective is to be able to build the entities of the model (read, write...) more independently according to the current state. The construction of the signature was also split for the same purpose. Pull-Request: #2813 Reviewed-by: Jean Privat <[email protected]>
2 parents 22fd41c + 0bf1b73 commit 3c92d1e

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)