OopPositiveBasicSyntax.ttcn 10.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
/******************************************************************************
 * Copyright (c) 2000-2021 Ericsson Telecom AB
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
 *
 * Contributors:
 *   Magyari, Miklos
 *
 * This module tests the basic class syntax
12
 * There should be no error markers for this file
13
14
15
16
17
18
 *
 * TTCN3 OOP extension v1.3.1
 * https://www.etsi.org/deliver/etsi_es/203700_203799/203790/01.03.01_60/es_203790v010301p.pdf)
 *
 ******************************************************************************/
 
19
module oopPositive language "TTCN-3:2018 Object-Oriented" { 
20
21

type component CT {
22
	port PT pt_PT;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
}

type port PT message { inout integer; } with { extension "internal" }
 
/*****************************
	class tests
*****************************/

// minimal classes
type class MinimalClass { }
type class @abstract MinimalAbstractClass { }
type class @final MinimalFinalClass { }
type class @trait MinimalTraitClass { }

// components
type class ClassCT runs on CT mtc CT system CT { }

// inheritance
type class BaseClass { }
type class @abstract AbstractBaseClass { }
type class @trait TraitBaseClass { }
type class @trait TraitBaseClass2 { }

type class SubClass0 extends object { }

type class SubClass1 extends BaseClass { 
	const integer m_const := 1;
}

type class SubClass2 extends BaseClass, TraitBaseClass {
	const integer m_const := 0;
}

type class SubClass3 extends BaseClass, TraitBaseClass, TraitBaseClass2 {
	var integer m_int;
}

60
61
type class SubClass4 extends SubClass1 {}

62
63
64
65
type class @abstract AbstractMethods {
	// functions without a statement block
	public function @abstract f_abs();
	public function f_get_string() return universal charstring;
66
67
68
69
70
71
72
73
74
75
76
77
	
	// implemented function
	function f_imp(in integer pl_x) return integer {
		return pl_x;
	}
}

type class InheritedAbstractMethods extends AbstractMethods {
	// inherited abstract function must be implemented
	public function f_abs() {
		const integer cl_int := 0;
	}
78
79
}

80
81
82
83
// members, methods and constructors
type class MembersClass {
	private var integer m_int_priv := 1;
	var integer m_int_prot := 2;
84
	var integer m_int_pub := 3;
85
86
87
88
89
	
	public function f_get1() return integer {
		return m_int_priv;
	}
	
90
91
	public function f_times2(in integer pl_times) return integer {
		return pl_times * m_int_prot;
92
93
	}
	
94
95
96
	create (integer pl_p1, integer pl_p2) {
		m_int_priv := pl_p1;
		m_int_prot := pl_p2;
97
98
99
	}
}

100
101
102
103
104
105
106
107
108
109
type class ImplicitConstructorClass {
	var integer m_int1;
	var charstring m_str1 := "abc";
	const float m_float1;
	const integer m_int2 := 1;			// should not be included in the constructor param list
	var template integer vt_int3;
	var integer @property m_prop1;
	var @internal integer @property m_prop2;	// should not be included in the constructor param list
}

110
type class @trait TraitClass {
111
112
113
	public function @abstract f_func(in integer pl_in);
}

114
115
116
117
118
119
type union MyUnion {
	integer choice1,
	charstring choice2
}

type class VariousMembers {
120
	private timer Timer;
121
	private const octetstring m_var_octet := 'ABCD'O; 
122
123
	var charstring m_var1 := "abc";
	private template MyUnion t_union := { choice1 := 12 }
124
	template MyUnion t_union2;
125
		
126
127
	create (charstring pl_p1, charstring pl_p2)  {
		m_var1 := pl_p2;
128
	}
129
130
}

131
type class @trait AbstractMembersClass { 
132
	function @abstract f();
133
134
	function @abstract f2(in integer pl_int);
	function @abstract f3(in integer pl_int) return charstring;
135
136
}

137
138
139
140
141
142
143
144
145
146
147
148
149
150
type class ConstructorOverride {
	var integer m_int := 0;
	create (integer pl_int) {
		m_int := pl_int;
	}
}

type class ConstructorOverrideSub {
	var float m_float;
	create (float pl_float) : ConstructorOverride(1) {
		m_float := pl_float;
	}
}

151
152
153
154
155
156
157
158
type class ConstantInitialization {
	const integer const_int; 
	
	create(integer pl_create_int) {
		const_int := pl_create_int;
	}
}

159
160
161
162
// runs on compatibility
type class RunsonClass1 runs on CT { }
type class RunsonClass2 extends RunsonClass1 runs on CT { }

163
164
165
166
167
168
169
170
// mtc compatibility
type class MtcClass1 mtc CT { }
type class MtcClass2 extends MtcClass1 mtc CT { }

// system compatibility
type class SystemClass1 system CT { }
type class SystemClass2 extends SystemClass1 system CT { }

171
172
173
// nested classes
type class OuterClass {
	private var integer m_int := 0;
174
	var charstring m_string := "abc";
175
	
176
	class NestedClass {
177
178
179
180
181
182
		private function f_dummy(in integer pl_param) return integer {
			return 1;
		}
		
		class DeeplyNested {
			const integer m_const := 0;
183
184
			class EvenDeeper {
				const charstring m_str := "abc";
185
				class Core {
186
187
188
189
190
					function f_inside(in integer pl_int) return float {
						return 0.1;
					}
				}
			}
191
192
193
194
		}
	}
}

195
196
// finally block
type class @abstract FinallyClass {
197
	private const integer m_const := 0;
198
} finally {
199
	log(this.m_const);
200
201
}

202
203
// `this` reference
type class ClassWithThis {
204
	var integer vl_a;
205
	const float vl_b;
206
207
208
209
210
211
212
213

	public function pl_dummy(in integer pl_int) return integer {
		return 1;
	}

	public function f_dummy2(in charstring pl_dummy) {
		var integer vl_int := this.pl_dummy(1);
	}
214
	
215
216
	create (integer pl_a, float pl_b) {
		this.vl_a := pl_a;
217
218
219
220
221
222
223
224
225
226
227
	}
}

// `super` reference
type class SuperBaseClass {
	private const integer m_const := 1;
	public function f_get_const() return integer {
		return m_const;
	}
}

228
229
230
231
232
233
234
235
236
237
238
239
// class method identifier reuse in method formal parameters or method body
type class ReuseClass {
	var integer pl_orig := 10;
	var charstring cl_orig := "abc";

	function f_reuse_in_paramlist(in charstring pl_orig) return integer {
		return 0;
	}

	function f_reuse_in_body(integer pl_param) {
		const float cl_orig := 0.1;
	}
240
241
242
243
244
245
246
247
248

	// test method id reuse in a nested StatmentBlock
	function f_reuse_in_body2(integer pl_param) {
		{
			{
				const float cl_orig := 0.1;
			}
		}
	}
249
250
}

251
type class SubClass5 extends SuperBaseClass {
252
	private const integer m_const2 := 2;
253
	private const integer m_const3 := 2;
254
	public function f_get_const2() return integer {
255
256
		return m_const2;
	}
257
258
		
	public function f_get_all_sum() return integer {
259
260
261
262
		var integer vl_sum := 0;
		const integer cl_const1 := 1;
		const integer cl_const2 := 2;
		vl_sum := cl_const1 + cl_const2;
263
		
264
		return vl_sum;
265
266
267
	}
} 

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
type class BaseFunctionClass {
	public function f_get_one() return integer {
		return 1; 
	}
}

type class FuncClass extends BaseFunctionClass {
	public function f_get_one() return charstring {
		return "xyz";
	}
	
	private function f_test_super() {
	  	// type mismatches 
		var integer vl_int := super.f_get_one();
		var charstring vl_cs:= f_get_one();
	}
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
	
	// class as a function parameter
	public function f_class_as_param(BaseFunctionClass pl_base) {
	  	// function call statement
		pl_base.f_get_one();
		
		// function call as an rvalue
		var integer vl_int := pl_base.f_get_one();
	}
	
		// class as a function parameter (inout)
	public function f_class_as_inout_param(inout BaseFunctionClass pl_base) {
	  	// function call statement
		pl_base.f_get_one();
		
		// function call as an rvalue
		var integer vl_int := pl_base.f_get_one();
	}
}

type class CastingClass extends BaseFunctionClass {
	private function f_priv_getpi(CastingClass pl_class) return float {
		return 3.1415;
	}

	public function f_using_cast(object pl_element) {
		// of-operator
		if (element of CastingClass) {
			// class casting
			var float vl_pi := f_priv_getpi(pl_element => CastingClass);
		}
	}
316
317
}

318
319
320
321
322
323
324
325
326
327
328
329
330
// private methods can be overridden in subclass
type class ClassWithPrivate {
	private function f_override(in float pl_float) return integer {
		return 1;
	}
}
 
type class ClassWithPrivateExt extends ClassWithPrivate {
	public function f_override(charstring pl_chr) return charstring {
		return pl_chr;
	}
}

331
332
// class properties
type class CorrectWithProperty { 
333
334
335
336
337
338
	private var integer heightVal;
	
	// auto property 
	private var integer @property width;
	
	// non-auto property
339
340
341
342
343
344
345
346
	var integer @property height { 
		@get => heightVal;  
		@set {   
			if (value > 0) {  
				heightVal := value;  
			} 
		} 
	} 
347
348
349
350
351
352
	
	// getter-only property
	private const float piVal := 3.1415;
	var float @property getPi {
		@get => piVal;
	}
353
354
355
356
357
358
	var float @property getPi2 {
		@get {
			return piVal;
		}
	}
	
359
360
361
362
363
364
365
366
367
368
	// 'value' manipulation
	private var integer @property valManip {
		@get => 10;
		@set {
			if (value > 42) {
				value := -value;
				heightVal := value;
			}
		}
	}
369
}
370

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
/***************************
exception handling
****************************/
function f_example() {
	
}

type integer MyInteger; 
type integer MyRange (0 .. 255); 

// function with multiple catch blocks
function f_example2() { 
 	f_example(); 
} catch (MyInteger e) { 
	
} catch (MyRange e) {  
 
} catch (integer e) { 
 
}

function f_with_finally() {
	// function body
} finally {
	// finally block   
}

function f_with_catches_and_finally(in charstring pl_chr) {
	return;
} catch (MyRange e) {  
 
} catch (integer e) { 
 
} finally {
	// finally block
} 

// function with a @control modifier
function @control f_example3(in integer pl_int) {
	
}

413
414
415
416
417
418
419
420
421
422
423
424
425
// raise exception
function f_with_exception(integer pl_int) return integer exception(integer) {
	if (pl_int > 100) {
		raise integer:0;
	}

	return pl_int * 2;
} catch (integer e) {
	log("Catch block");
} finally {
	log("Finally block");
}

426
testcase tc_basicSyntax() runs on CT {
427
428
	var object vl_obj := MinimalClass.create;

429
// basic instantiation and constructor calls
430
431
432
433
	// constructor call without parameters
	var MinimalClass vl_minimalClass := MinimalClass.create;
	// constructor call with empty parameter list
	var MinimalClass vl_minimalClass2 := MinimalClass.create();
434
	var ClassWithThis vl_thisClass := ClassWithThis.create(12, 13.0);
435
	var VariousMembers vl_various := VariousMembers.create("abc", "def");
436
437
438

// class member access
	var integer vl_intval := vl_thisClass.vl_a;
439
440
	var SubClass5 vl_sub5 := SubClass5.create;
	vl_intval := vl_sub5.f_get_all_sum();
441
442

// class method call
443
	vl_sub5.f_get_all_sum();
444
445

// class of-operator
446
	var OuterClass vl_outerClass := OuterClass.create(0, "0");
447
448
449
	if (vl_outerClass of OuterClass) {
		vl_outerClass.m_string := "xyz";
	}
450
	
451
452
453
454
455
456
// class casting
	var BaseClass vl_base := BaseClass.create;
	var object vl_casted := vl_base => SubClass1;
	var SubClass4 vl_subclass4 := SubClass4.create;
	var object vl_casted2 := vl_subclass4 => BaseClass;
	
457
458
// nested class member reference
	var float vl_float := vl_outerClass.NestedClass.DeeplyNested.EvenDeeper.Core.f_inside(1);
459
460
461
	
// implicit constructor use
	var ImplicitConstructorClass vl_impl := ImplicitConstructorClass.create(1, "xyz", 3.14, 2, 5); 
462
463
464
465
466
467
468
}

control {
	execute(tc_basicSyntax());
}

}