Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Eclipse Projects
Eclipse Titan
titan.EclipsePlug-ins
Commits
28979b4d
Commit
28979b4d
authored
Sep 08, 2021
by
Adam Knapp
Browse files
Implemented conjunction, implication and dynamic templates, part 1
issues
#413
,
#414
and
#415
Signed-off-by:
Adam Knapp
<
adam.knapp@ericsson.com
>
parent
2d8135f2
Changes
14
Hide whitespace changes
Inline
Side-by-side
org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/Identifier.java
View file @
28979b4d
...
...
@@ -467,6 +467,7 @@ public class Identifier implements ILocateableNode, IVisitableNode {
{
"check__"
,
"check"
,
"check_"
},
{
"clear__"
,
"clear"
,
"clear_"
},
{
"complement__"
,
"complement"
,
"complement_"
},
{
"conjunct__"
,
"conjunct"
,
"conjunct_"
},
{
"connect__"
,
"connect"
,
"connect_"
},
{
"control__"
,
"control"
,
"control_"
},
{
"create__"
,
"create"
,
"create_"
},
...
...
@@ -494,6 +495,7 @@ public class Identifier implements ILocateableNode, IVisitableNode {
{
"halt__"
,
"halt"
,
"halt_"
},
{
"hexstring__"
,
"hexstring"
,
"hexstring_"
},
{
"ifpresent__"
,
"ifpresent"
,
"ifpresent_"
},
{
"implies__"
,
"implies"
,
"implies_"
},
{
"import__"
,
"import"
,
"import_"
},
{
"in__"
,
"in"
,
"in_"
},
{
"inconc__"
,
"inconc"
,
"inconc_"
},
...
...
org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/Reference.java
View file @
28979b4d
...
...
@@ -80,9 +80,13 @@ public class Reference extends ASTNode implements ILocateableNode, IIncrementall
private
static
final
String
VALUENOTSETTER
=
"A property getter cannot have a `value` reference"
;
public
enum
Ref_Type
{
/** basic reference (not related to a class scope or a dynamic template) */
REF_BASIC
,
/** reference to the current class object */
REF_THIS
,
/** reference to the superclass */
REF_SUPER
,
/** reference to the value being matched in a dynamic template or to be used in an OOP property */
REF_VALUE
}
...
...
org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/statements/Return_Statement.java
View file @
28979b4d
...
...
@@ -51,6 +51,7 @@ public final class Return_Statement extends Statement {
private
static
final
String
USAGEINCONTROLPART
=
"Return statement cannot be used in the control part. It is allowed only in functions and altsteps"
;
private
static
final
String
RETURNINDESTRUCTOR
=
"Return statement cannot be used in a class destructor"
;
private
static
final
String
INVALIDSETTERRETURN
=
"Return statement cannot be used in a property setter"
;
private
static
final
String
RETURNINDYNAMICTEMPLATE
=
"The dynamic template's statement block should return a boolean value"
;
private
static
final
String
FULLNAMEPART
=
".returnexpression"
;
private
static
final
String
STATEMENT_NAME
=
"return"
;
private
static
final
String
RETURNTYPEEXPECTED
=
"Return type `{0}'' expected"
;
...
...
@@ -171,6 +172,11 @@ public final class Return_Statement extends Statement {
location
.
reportSemanticError
(
MessageFormat
.
format
(
MISSINGVALUE
,
returnType
.
getTypename
()));
break
;
}
if
(
myStatementBlock
.
isInDynamicTemplate
()
&&
!
returnType
.
getTypetype
().
equals
(
Type_type
.
TYPE_BOOL
))
{
template
.
getLocation
().
reportSemanticError
(
RETURNINDYNAMICTEMPLATE
);
break
;
}
if
(!
template
.
isValue
(
timestamp
))
{
template
.
getLocation
().
reportSemanticError
(
SPECIFICVALUEEXPECTED
);
break
;
...
...
org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/statements/StatementBlock.java
View file @
28979b4d
...
...
@@ -44,6 +44,8 @@ import org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Testcase;
import
org.eclipse.titan.designer.AST.TTCN3.definitions.Definition
;
import
org.eclipse.titan.designer.AST.TTCN3.definitions.FormalParameterList
;
import
org.eclipse.titan.designer.AST.TTCN3.statements.Statement.Statement_type
;
import
org.eclipse.titan.designer.AST.TTCN3.templates.DynamicMatch_template
;
import
org.eclipse.titan.designer.AST.TTCN3.templates.TTCN3Template
;
import
org.eclipse.titan.designer.AST.TTCN3.types.ClassTypeBody
;
import
org.eclipse.titan.designer.AST.TTCN3.types.Component_Type
;
import
org.eclipse.titan.designer.compiler.JavaGenData
;
...
...
@@ -109,6 +111,9 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
/** the definition containing this statement block. */
private
Definition
myDefinition
;
/** the dynamic template, if this is the statement block of a dynamic template */
private
DynamicMatch_template
dynamicTemplate
;
/** the time when this statement block was check the last time. */
private
CompilationTimeStamp
lastTimeChecked
;
...
...
@@ -135,6 +140,7 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
/** Formal parameter list with only one member.
* It is used to support the special 'value' keyword in class properties
* and in dynamic templates
*/
private
FormalParameterList
valueParamList
;
...
...
@@ -1132,7 +1138,7 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
}
}
/**
* Sets a formal parameter list for this statement block.
* It is used by class properties for the special keyword 'value'.
...
...
@@ -1141,7 +1147,7 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
public
void
setValueParamList
(
FormalParameterList
fpl
)
{
this
.
valueParamList
=
fpl
;
}
/**
* Gets a formal parameter list for this statement block.
* It is used by class properties for the special keyword 'value'.
...
...
@@ -1154,7 +1160,7 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
public
boolean
ownerIsProperty
()
{
return
this
.
ownerIsProperty
;
}
/**
* Checks wheter a statement block belongs to a property setter
* @return
...
...
@@ -1166,7 +1172,7 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
return
false
;
}
/**
* Checks wheter a statement block belongs to a property getter
* @return
...
...
@@ -1178,18 +1184,68 @@ public final class StatementBlock extends TTCN3Scope implements ILocateableNode,
return
false
;
}
/**
* Sets the flag to indicate it is a statement block of a property getter
*/
public
void
setIsGetter
()
{
this
.
isPropertyGetter
=
true
;
}
/**
* Sets the flag to indicate it is a statement block of a property setter
*/
public
void
setIsSetter
()
{
this
.
isPropertySetter
=
true
;
}
/**
* Returns whether this statement block has a formal parameter list.
* It is used by class properties and by dynamic matching for the special keyword 'value'.
* @return {@code true} if a formal parameter list is set, otherwise {@code false}
*/
public
boolean
hasValueParamList
()
{
return
valueParamList
!=
null
;
}
/**
* Returns the dynamic template of this statement block
* @return {@code null}, if this is not the statement block of a dynamic template
*/
public
DynamicMatch_template
getDynamicTemplate
()
{
if
(
dynamicTemplate
!=
null
)
{
return
dynamicTemplate
;
}
if
(
myStatementBlock
!=
null
)
{
return
myStatementBlock
.
getDynamicTemplate
();
}
ErrorReporter
.
INTERNAL_ERROR
();
return
null
;
}
/**
* Sets the dynamic template for this statement block
* @param template
*/
public
void
setDynamicTemplate
(
final
TTCN3Template
template
)
{
if
(
template
instanceof
DynamicMatch_template
)
{
dynamicTemplate
=
(
DynamicMatch_template
)
template
;
}
else
{
ErrorReporter
.
INTERNAL_ERROR
(
"TTCN3Template is not type of DynamicMatch_template"
);
}
}
/**
* Returns whether this statement block is in a dynamic template
* @return {@code true} if this statement block is in a dynamic template, otherwise {@code false}
*/
public
boolean
isInDynamicTemplate
()
{
if
(
dynamicTemplate
!=
null
)
{
return
true
;
}
if
(
myStatementBlock
!=
null
)
{
return
myStatementBlock
.
isInDynamicTemplate
();
}
return
false
;
}
}
org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/templates/ConjunctionMatch_template.java
0 → 100644
View file @
28979b4d
/******************************************************************************
* 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
******************************************************************************/
package
org.eclipse.titan.designer.AST.TTCN3.templates
;
import
java.text.MessageFormat
;
import
java.util.ArrayList
;
import
org.eclipse.titan.common.logging.ErrorReporter
;
import
org.eclipse.titan.designer.AST.Assignment
;
import
org.eclipse.titan.designer.AST.IType
;
import
org.eclipse.titan.designer.AST.Location
;
import
org.eclipse.titan.designer.AST.Module
;
import
org.eclipse.titan.designer.AST.NULL_Location
;
import
org.eclipse.titan.designer.AST.Reference
;
import
org.eclipse.titan.designer.AST.IType.Type_type
;
import
org.eclipse.titan.designer.AST.TTCN3.Expected_Value_type
;
import
org.eclipse.titan.designer.AST.TTCN3.TemplateRestriction
;
import
org.eclipse.titan.designer.AST.TTCN3.values.expressions.ExpressionStruct
;
import
org.eclipse.titan.designer.compiler.JavaGenData
;
import
org.eclipse.titan.designer.parsers.CompilationTimeStamp
;
/**
* Represents a template for conjunction matching.
*
* @author Adam Knapp
* */
public
class
ConjunctionMatch_template
extends
CompositeTemplate
{
public
ConjunctionMatch_template
(
final
ListOfTemplates
templates
)
{
super
(
templates
);
}
@Override
/** {@inheritDoc} */
public
boolean
checkExpressionSelfReferenceTemplate
(
final
CompilationTimeStamp
timestamp
,
final
Assignment
lhs
)
{
for
(
int
i
=
0
,
size
=
templates
.
getNofTemplates
();
i
<
size
;
i
++)
{
if
(
templates
.
getTemplateByIndex
(
i
).
checkExpressionSelfReferenceTemplate
(
timestamp
,
lhs
))
{
return
true
;
}
}
return
false
;
}
@Override
/** {@inheritDoc} */
public
boolean
checkPresentRestriction
(
final
CompilationTimeStamp
timestamp
,
final
String
definitionName
,
final
Location
usageLocation
)
{
checkRestrictionCommon
(
timestamp
,
definitionName
,
TemplateRestriction
.
Restriction_type
.
TR_PRESENT
,
usageLocation
);
boolean
needsRuntimeCheck
=
false
;
for
(
int
i
=
0
,
size
=
templates
.
getNofTemplates
();
i
<
size
;
i
++)
{
final
ITTCN3Template
component
=
templates
.
getTemplateByIndex
(
i
);
if
(
component
.
checkPresentRestriction
(
timestamp
,
definitionName
,
usageLocation
))
{
needsRuntimeCheck
=
true
;
}
}
return
needsRuntimeCheck
;
}
@Override
/** {@inheritDoc} */
public
void
checkSpecificValue
(
final
CompilationTimeStamp
timestamp
,
final
boolean
allowOmit
)
{
getLocation
().
reportSemanticError
(
"A specific value expected instead of a conjunction match"
);
}
@Override
/** {@inheritDoc} */
public
boolean
checkThisTemplateGeneric
(
final
CompilationTimeStamp
timestamp
,
final
IType
type
,
final
boolean
isModified
,
final
boolean
allowOmit
,
final
boolean
allowAnyOrOmit
,
final
boolean
subCheck
,
final
boolean
implicitOmit
,
final
Assignment
lhs
)
{
if
(
type
==
null
)
{
return
false
;
}
boolean
selfReference
=
false
;
for
(
int
i
=
0
,
size
=
templates
.
getNofTemplates
();
i
<
size
;
i
++)
{
final
TTCN3Template
component
=
templates
.
getTemplateByIndex
(
i
);
component
.
setMyGovernor
(
type
);
final
ITTCN3Template
temporalComponent
=
type
.
checkThisTemplateRef
(
timestamp
,
component
);
selfReference
|=
temporalComponent
.
checkThisTemplateGeneric
(
timestamp
,
type
,
false
,
false
,
true
,
subCheck
,
implicitOmit
,
lhs
);
}
checkLengthRestriction
(
timestamp
,
type
);
if
(!
allowOmit
&&
isIfpresent
)
{
if
(
location
!=
null
&&
!(
location
instanceof
NULL_Location
))
{
location
.
reportSemanticError
(
"`ifpresent' is not allowed here"
);
}
}
if
(
subCheck
)
{
type
.
checkThisTemplateSubtype
(
timestamp
,
this
);
}
return
selfReference
;
}
@Override
/** {@inheritDoc} */
public
void
generateCodeInit
(
final
JavaGenData
aData
,
final
StringBuilder
source
,
final
String
name
)
{
if
(
lastTimeBuilt
!=
null
&&
!
lastTimeBuilt
.
isLess
(
aData
.
getBuildTimstamp
()))
{
return
;
}
lastTimeBuilt
=
aData
.
getBuildTimstamp
();
aData
.
addBuiltinTypeImport
(
"Base_Template.template_sel"
);
final
ArrayList
<
Integer
>
variables
=
new
ArrayList
<
Integer
>();
long
fixedPart
=
0
;
for
(
int
i
=
0
;
i
<
templates
.
getNofTemplates
();
i
++)
{
final
TTCN3Template
templateListItem
=
templates
.
getTemplateByIndex
(
i
);
if
(
templateListItem
.
getTemplatetype
()
==
Template_type
.
ALL_FROM
)
{
variables
.
add
(
i
);
}
else
{
fixedPart
++;
}
}
final
String
typeName
=
myGovernor
.
getGenNameTemplate
(
aData
,
source
);
if
(
variables
.
size
()
>
0
)
{
final
StringBuilder
preamble
=
new
StringBuilder
();
final
StringBuilder
setType
=
new
StringBuilder
();
final
StringBuilder
variableReferences
[]
=
new
StringBuilder
[
templates
.
getNofTemplates
()];
setType
.
append
(
MessageFormat
.
format
(
"{0}.set_type(template_sel.VALUE_LIST, {1}"
,
name
,
fixedPart
));
for
(
int
v
=
0
;
v
<
variables
.
size
();
v
++)
{
TTCN3Template
template
=
templates
.
getTemplateByIndex
(
variables
.
get
(
v
));
// the template must be all from
if
(
template
instanceof
All_From_Template
)
{
template
=
((
All_From_Template
)
template
).
getAllFrom
();
}
final
Reference
reference
=
((
SpecificValue_Template
)
template
).
getReference
();
final
Assignment
assignment
=
reference
.
getRefdAssignment
(
CompilationTimeStamp
.
getBaseTimestamp
(),
false
);
setType
.
append
(
" + "
);
final
ExpressionStruct
expression
=
new
ExpressionStruct
();
reference
.
generateConstRef
(
aData
,
expression
);
if
(
expression
.
preamble
.
length
()
>
0
)
{
preamble
.
append
(
expression
.
preamble
);
}
switch
(
assignment
.
getAssignmentType
())
{
case
A_CONST:
case
A_EXT_CONST:
case
A_MODULEPAR:
case
A_VAR:
case
A_PAR_VAL:
case
A_PAR_VAL_IN:
case
A_PAR_VAL_OUT:
case
A_PAR_VAL_INOUT:
case
A_FUNCTION_RVAL:
case
A_EXT_FUNCTION_RVAL:
if
(
assignment
.
getType
(
CompilationTimeStamp
.
getBaseTimestamp
()).
fieldIsOptional
(
reference
.
getSubreferences
()))
{
expression
.
expression
.
append
(
".constGet()"
);
}
break
;
default
:
break
;
}
variableReferences
[
variables
.
get
(
v
)]
=
expression
.
expression
;
setType
.
append
(
expression
.
expression
);
setType
.
append
(
".n_elem()"
);
}
source
.
append
(
preamble
);
source
.
append
(
setType
);
source
.
append
(
");\n"
);
final
StringBuilder
shifty
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
templates
.
getNofTemplates
();
i
++)
{
final
TTCN3Template
template
=
templates
.
getTemplateByIndex
(
i
);
switch
(
template
.
getTemplatetype
())
{
case
ALL_FROM:
{
// the template must be all from
final
StringBuilder
storedExpression
=
variableReferences
[
i
];
source
.
append
(
MessageFormat
.
format
(
"for (int i_i = 0, i_lim = {0}.n_elem(); i_i < i_lim; ++i_i ) '{'\n"
,
storedExpression
));
final
String
embeddedName
=
MessageFormat
.
format
(
"{0}.list_item({1}{2} + i_i)"
,
name
,
i
,
shifty
);
((
All_From_Template
)
template
).
generateCodeInitAllFrom
(
aData
,
source
,
embeddedName
,
storedExpression
);
source
.
append
(
"}\n"
);
shifty
.
append
(
MessageFormat
.
format
(
"-1 + {0}.n_elem()"
,
storedExpression
));
break
;
}
default
:
if
(
template
.
needsTemporaryReference
())
{
final
String
tempId
=
aData
.
getTemporaryVariableName
();
source
.
append
(
"{\n"
);
source
.
append
(
MessageFormat
.
format
(
"final {0} {1} = {2}.list_item({3}{4});\n"
,
typeName
,
tempId
,
name
,
i
,
shifty
));
template
.
generateCodeInit
(
aData
,
source
,
tempId
);
source
.
append
(
"}\n"
);
}
else
{
final
String
embeddedName
=
MessageFormat
.
format
(
"{0}.list_item({1}{2})"
,
name
,
i
,
shifty
);
template
.
generateCodeInit
(
aData
,
source
,
embeddedName
);
}
break
;
}
}
}
else
{
source
.
append
(
MessageFormat
.
format
(
"{0}.set_type(template_sel.VALUE_LIST, {1});\n"
,
name
,
templates
.
getNofTemplates
()));
for
(
int
i
=
0
;
i
<
templates
.
getNofTemplates
();
i
++)
{
final
TTCN3Template
template
=
templates
.
getTemplateByIndex
(
i
);
if
(
template
.
needsTemporaryReference
())
{
final
String
tempId
=
aData
.
getTemporaryVariableName
();
source
.
append
(
"{\n"
);
source
.
append
(
MessageFormat
.
format
(
"final {0} {1} = {2}.list_item({3});\n"
,
typeName
,
tempId
,
name
,
i
));
template
.
generateCodeInit
(
aData
,
source
,
tempId
);
source
.
append
(
"}\n"
);
}
else
{
final
String
embeddedName
=
MessageFormat
.
format
(
"{0}.list_item({1})"
,
name
,
i
);
template
.
generateCodeInit
(
aData
,
source
,
embeddedName
);
}
}
}
if
(
lengthRestriction
!=
null
)
{
if
(
getCodeSection
()
==
CodeSectionType
.
CS_POST_INIT
)
{
lengthRestriction
.
reArrangeInitCode
(
aData
,
source
,
myScope
.
getModuleScopeGen
());
}
lengthRestriction
.
generateCodeInit
(
aData
,
source
,
name
);
}
if
(
isIfpresent
)
{
source
.
append
(
name
);
source
.
append
(
".set_ifPresent();\n"
);
}
}
@Override
/** {@inheritDoc} */
public
IType
getExpressionGovernor
(
final
CompilationTimeStamp
timestamp
,
final
Expected_Value_type
expectedValue
)
{
if
(
myGovernor
!=
null
)
{
return
myGovernor
;
}
for
(
int
i
=
0
,
size
=
templates
.
getNofTemplates
();
i
<
size
;
i
++)
{
final
IType
type
=
templates
.
getTemplateByIndex
(
i
).
getExpressionGovernor
(
timestamp
,
expectedValue
);
if
(
type
!=
null
)
{
return
type
;
}
}
return
null
;
}
@Override
/** {@inheritDoc} */
public
Type_type
getExpressionReturntype
(
final
CompilationTimeStamp
timestamp
,
final
Expected_Value_type
expectedValue
)
{
if
(
getIsErroneous
(
timestamp
))
{
return
Type_type
.
TYPE_UNDEFINED
;
}
for
(
int
i
=
0
,
size
=
templates
.
getNofTemplates
();
i
<
size
;
i
++)
{
final
Type_type
type
=
templates
.
getTemplateByIndex
(
i
).
getExpressionReturntype
(
timestamp
,
expectedValue
);
if
(!
Type_type
.
TYPE_UNDEFINED
.
equals
(
type
))
{
return
type
;
}
}
return
Type_type
.
TYPE_UNDEFINED
;
}
@Override
protected
String
getNameForStringRep
()
{
return
"conjunct"
;
}
@Override
/** {@inheritDoc} */
public
StringBuilder
getSingleExpression
(
final
JavaGenData
aData
,
final
boolean
castIsNeeded
)
{
final
StringBuilder
result
=
new
StringBuilder
();
ErrorReporter
.
INTERNAL_ERROR
(
"FATAL ERROR while processing conjunction match `"
+
getFullName
()
+
"''"
);
return
result
;
}
@Override
/** {@inheritDoc} */
public
Template_type
getTemplatetype
()
{
return
Template_type
.
CONJUNCTION_MATCH
;
}
@Override
/** {@inheritDoc} */
public
String
getTemplateTypeName
()
{
if
(
isErroneous
)
{
return
"erroneous conjunction match"
;
}
return
"conjunction match"
;
}
@Override
/** {@inheritDoc} */
public
boolean
hasSingleExpression
()
{
return
false
;
}
@Override
/** {@inheritDoc} */
public
boolean
needsTemporaryReference
()
{
return
true
;
}
@Override
/** {@inheritDoc} */
public
void
reArrangeInitCode
(
final
JavaGenData
aData
,
final
StringBuilder
source
,
final
Module
usageModule
)
{
for
(
int
i
=
0
;
i
<
templates
.
getNofTemplates
();
i
++)
{
templates
.
getTemplateByIndex
(
i
).
reArrangeInitCode
(
aData
,
source
,
usageModule
);
}
if
(
lengthRestriction
!=
null
)
{
lengthRestriction
.
reArrangeInitCode
(
aData
,
source
,
usageModule
);
}
}
}
org.eclipse.titan.designer/src/org/eclipse/titan/designer/AST/TTCN3/templates/DynamicMatch_template.java
0 → 100644
View file @
28979b4d
/******************************************************************************
* 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
******************************************************************************/
package
org.eclipse.titan.designer.AST.TTCN3.templates
;
import
org.eclipse.titan.common.logging.ErrorReporter
;
import
org.eclipse.titan.designer.AST.Assignment
;
import
org.eclipse.titan.designer.AST.IReferenceChain
;
import
org.eclipse.titan.designer.AST.Reference
;
import
org.eclipse.titan.designer.AST.Scope
;
import
org.eclipse.titan.designer.AST.TTCN3.definitions.FormalParameter
;
import
org.eclipse.titan.designer.AST.TTCN3.definitions.FormalParameterList
;
import
org.eclipse.titan.designer.AST.TTCN3.statements.Return_Statement
;
import
org.eclipse.titan.designer.AST.TTCN3.statements.StatementBlock
;
import
org.eclipse.titan.designer.compiler.JavaGenData
;
import
org.eclipse.titan.designer.parsers.CompilationTimeStamp
;
/**
* Represents a template for implication matching.
*
* @author Adam Knapp
* */
public
class
DynamicMatch_template
extends
TTCN3Template
{
/** function reference used in defining the dynamic template, not owned */
private
Reference
reference
;
/** statement block of the dynamic template
* (if the template is defined using a function reference instead of a statement block,
* then a new statement block is generated with a return statement containing the function reference) */
private
StatementBlock
statementBlock
;
/** Pointer to the formal parameter list if this template is part of
* a parameterized template. It is {@code null} otherwise. */
private
FormalParameterList
formalParameterList
;
public
DynamicMatch_template
(
final
Reference
reference
)
{
// '@dynamic F' is equivalent to '@dynamic { return F(value); }'
// the parser has already added the function parameter 'value',
// the rest of the statement block is constructed here
this
.
reference
=
reference
;
statementBlock
=
new
StatementBlock
();
statementBlock
.
setDynamicTemplate
(
this
);
statementBlock
.
addStatement
(
new
Return_Statement
(
new
Referenced_Template
(
reference
)));
if
(
reference
!=
null
)
{
reference
.
setFullNameParent
(
this
);