Commit 9d430554 authored by Adam Knapp's avatar Adam Knapp
Browse files

OOP: property semantic check improvements #427


Signed-off-by: Adam Knapp's avatarAdam Knapp <adam.knapp@ericsson.com>
parent b034d937
......@@ -15,7 +15,6 @@ import org.eclipse.titan.designer.AST.Assignment.Assignment_type;
import org.eclipse.titan.designer.AST.GovernedSimple.CodeSectionType;
import org.eclipse.titan.designer.AST.INamedNode;
import org.eclipse.titan.designer.AST.IType;
import org.eclipse.titan.designer.AST.IType.Type_type;
import org.eclipse.titan.designer.AST.IType.ValueCheckingOptions;
import org.eclipse.titan.designer.AST.IValue;
import org.eclipse.titan.designer.AST.ReferenceFinder;
......@@ -59,7 +58,6 @@ public final class Return_Statement extends Statement {
private static final String INVALIDRETURNINDYNAMICTEMPLATESB2 = "A specific value without matching symbols was expected as return value";
private static final String FULLNAMEPART = ".returnexpression";
private static final String STATEMENT_NAME = "return";
private static final String RETURNTYPEEXPECTED = "Return type `{0}'' expected";
private final TTCN3Template template;
private boolean genRestrictionCheck = false;
......@@ -194,18 +192,21 @@ public final class Return_Statement extends Statement {
final IType propType = property.getFieldType(timestamp, null, 0, Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false);
location.reportSemanticError(MessageFormat.format(MISSINGTEMPLATE, propType.getTypename()));
} else {
final Type_type templateType = template.getExpressionReturntype(timestamp, Expected_Value_type.EXPECTED_DYNAMIC_VALUE);
if (templateType != property.getTypetypeTtcn3()) {
final IType propType = property.getFieldType(timestamp, null, 0, Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false);
location.reportSemanticError(MessageFormat.format(RETURNTYPEEXPECTED, propType.getTypename()));
template.setMyGovernor(propType);
final IValue value = template.getValue();
if (value != null) {
value.setMyGovernor(propType);
propType.checkThisValueRef(timestamp, value);
propType.checkThisValue(timestamp, value, null, new ValueCheckingOptions(Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false, false, true, false, false));
}
}
return;
break;
}
}
if (myStatementBlock.isPropertySetter()) {
location.reportSemanticError(INVALIDSETTERRETURN);
return;
break;
}
}
break;
......
......@@ -14,12 +14,14 @@ import java.util.List;
import org.eclipse.titan.designer.AST.Assignment;
import org.eclipse.titan.designer.AST.Assignment.Assignment_type;
import org.eclipse.titan.designer.AST.FieldSubReference;
import org.eclipse.titan.designer.AST.IReferenceChain;
import org.eclipse.titan.designer.AST.IType;
import org.eclipse.titan.designer.AST.Identifier;
import org.eclipse.titan.designer.AST.Identifier.Identifier_type;
import org.eclipse.titan.designer.AST.Location;
import org.eclipse.titan.designer.AST.Reference;
import org.eclipse.titan.designer.AST.Reference.Ref_Type;
import org.eclipse.titan.designer.AST.ReferenceChain;
import org.eclipse.titan.designer.AST.Scope;
import org.eclipse.titan.designer.AST.Type;
......@@ -30,10 +32,14 @@ import org.eclipse.titan.designer.AST.TTCN3.definitions.Definition;
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.definitions.VisibilityModifier;
import org.eclipse.titan.designer.AST.TTCN3.statements.Assignment_Statement;
import org.eclipse.titan.designer.AST.TTCN3.statements.Return_Statement;
import org.eclipse.titan.designer.AST.TTCN3.statements.StatementBlock;
import org.eclipse.titan.designer.AST.TTCN3.statements.StatementBlock.ReturnStatus_type;
import org.eclipse.titan.designer.AST.TTCN3.templates.ITTCN3Template;
import org.eclipse.titan.designer.AST.TTCN3.templates.SpecificValue_Template;
import org.eclipse.titan.designer.AST.TTCN3.templates.TTCN3Template;
import org.eclipse.titan.designer.AST.TTCN3.values.Referenced_Value;
import org.eclipse.titan.designer.compiler.JavaGenData;
import org.eclipse.titan.designer.parsers.CompilationTimeStamp;
......@@ -42,7 +48,6 @@ import org.eclipse.titan.designer.parsers.CompilationTimeStamp;
*
* @author Miklos Magyari
* */
public final class Property_Type extends Type {
private static final String INITIALVALUEWITHOUTSETTER = "A property without a setter cannot have an initial value";
private static final String EMPTYBODY = "An empty property body is not allowed";
......@@ -51,6 +56,9 @@ public final class Property_Type extends Type {
private static final String MODIFIERFINALABSTRACT = "Property {0} cannot be both abstract and final";
private static final String ABSTRACTWITHBODY = "Abstract {0} should not have a body";
private static final String GETTER = "getter";
private static final String SETTER = "setter";
/** type of the property */
private Type myType;
......@@ -64,7 +72,7 @@ public final class Property_Type extends Type {
private TTCN3Template getterTemplate;
/** template definition of the property setter, if defined */
private TTCN3Template setterTemplate;
private Assignment_Statement setterAssignment;
/** a template containing the initial value for the property */
private TTCN3Template initValTemplate;
......@@ -107,7 +115,7 @@ public final class Property_Type extends Type {
this.setterStatementBlock = null;
this.getterStatementBlock = null;
this.setterTemplate = null;
this.setterAssignment = null;
this.getterTemplate = null;
this.initValTemplate = null;
this.isAutoProperty = true;
......@@ -123,8 +131,15 @@ public final class Property_Type extends Type {
}
/**
* Sets the statement block for the property getter
* @param sb
* Sets the statement block for the property setter. If it is {@code null} it generates one.
* @param sb Statement block of the property setter
* @param template Template of the property setter
* @param modifier Visibility
* @param isAbstract
* @param isFinal
* @param isDeterministic
* @param visibilityLocation
* @param modifierLocation
*/
public void setStatementBlockGetter(StatementBlock sb, TTCN3Template template, VisibilityModifier modifier,
boolean isAbstract, boolean isFinal, boolean isDeterministic,
......@@ -137,20 +152,34 @@ public final class Property_Type extends Type {
isGetterDeterministic = isDeterministic;
getterVisibilityLocation = visibilityLocation;
getterModifierLocation = modifierLocation;
getterTemplate = template;
if (getterStatementBlock == null && getterTemplate != null) {
final Return_Statement rs = new Return_Statement(getterTemplate);
rs.setLocation(getterTemplate.getLocation());
getterStatementBlock = new StatementBlock();
getterStatementBlock.addStatement(rs);
}
if (getterStatementBlock != null) {
getterStatementBlock.setIsGetter();
getterStatementBlock.setOwnerIsProperty();
getterStatementBlock.setFullNameParent(this);
}
getterTemplate = template;
}
/**
* Sets the statement block for the property setter
* @param sb
* Sets the statement block for the property setter. If it is {@code null} it generates one.
* @param sb Statement block of the property setter
* @param assignment Assignment statement of the property setter
* @param modifier Visibility
* @param isAbstract
* @param isFinal
* @param isDeterministic
* @param visibilityLocation
* @param modifierLocation
*/
public void setStatementBlockSetter(StatementBlock sb, TTCN3Template template, VisibilityModifier modifier,
public void setStatementBlockSetter(StatementBlock sb, Assignment_Statement assignment, VisibilityModifier modifier,
boolean isAbstract, boolean isFinal, boolean isDeterministic,
Location visibilityLocation, Location modifierLocation) {
hasSetter = true;
......@@ -160,13 +189,18 @@ public final class Property_Type extends Type {
isSetterDeterministic = isDeterministic;
setterVisibilityLocation = visibilityLocation;
setterModifierLocation = modifierLocation;
setterAssignment = assignment;
if (setterStatementBlock == null && setterAssignment != null) {
setterStatementBlock = new StatementBlock();
setterStatementBlock.addStatement(setterAssignment);
}
if (setterStatementBlock != null) {
setterStatementBlock.setIsSetter();
setterStatementBlock.setOwnerIsProperty();
setterStatementBlock.setFullNameParent(this);
}
setterTemplate = template;
}
@Override
......@@ -178,7 +212,7 @@ public final class Property_Type extends Type {
lastTimeChecked = timestamp;
if (hasBody == true && hasGetter() == false && hasSetter() == false) {
if (hasBody && !hasGetter() && !hasSetter()) {
getLocation().reportSemanticError(EMPTYBODY);
}
......@@ -194,7 +228,7 @@ public final class Property_Type extends Type {
setterStatementBlock.setValueParamList(fpList);
setterStatementBlock.check(timestamp);
}
if (initValTemplate != null && hasSetter() == false) {
if (initValTemplate != null && !hasSetter()) {
initValTemplate.getLocation().reportSemanticError(INITIALVALUEWITHOUTSETTER);
initValTemplate.setIsErroneous(true);
}
......@@ -211,24 +245,20 @@ public final class Property_Type extends Type {
if (isGetterAbstract) {
if (isGetterFinal) {
getterModifierLocation.reportSemanticError(MessageFormat.format(
MODIFIERFINALABSTRACT, "getter"));
getterModifierLocation.reportSemanticError(MessageFormat.format(MODIFIERFINALABSTRACT, GETTER));
}
if (getterStatementBlock != null || getterTemplate != null) {
final Location getterLoc = getterStatementBlock == null ? getterTemplate.getLocation() : getterStatementBlock.getLocation();
getterLoc.reportSemanticError(MessageFormat.format(
ABSTRACTWITHBODY, "getter"));
getterLoc.reportSemanticError(MessageFormat.format(ABSTRACTWITHBODY, GETTER));
}
}
if (isSetterAbstract) {
if (isSetterFinal) {
setterModifierLocation.reportSemanticError(MessageFormat.format(
MODIFIERFINALABSTRACT, "setter"));
setterModifierLocation.reportSemanticError(MessageFormat.format(MODIFIERFINALABSTRACT, SETTER));
}
if (setterStatementBlock != null || setterTemplate != null) {
final Location setterLoc = setterStatementBlock == null ? setterTemplate.getLocation() : setterStatementBlock.getLocation();
setterLoc.reportSemanticError(MessageFormat.format(
ABSTRACTWITHBODY, "setter"));
if (setterStatementBlock != null || setterAssignment != null) {
final Location setterLoc = setterStatementBlock == null ? setterAssignment.getLocation() : setterStatementBlock.getLocation();
setterLoc.reportSemanticError(MessageFormat.format(ABSTRACTWITHBODY, SETTER));
}
}
}
......@@ -264,22 +294,14 @@ public final class Property_Type extends Type {
* @return
*/
public boolean hasSetter() {
if (isAutoProperty) {
return true;
}
return hasSetter;
return isAutoProperty ? true : hasSetter;
}
/** Checks whether the property has a getter definition
* @return
*/
public boolean hasGetter() {
if (isAutoProperty) {
return true;
}
return hasGetter;
return isAutoProperty ? true : hasGetter;
}
public void setInitValTemplate(TTCN3Template template) {
......@@ -375,11 +397,11 @@ public final class Property_Type extends Type {
return null;
}
/** Sets the definition of the getter/setter statement blocks. It should point to a Def_Var instance.
*
/**
* Sets the definition of the getter/setter statement blocks. It should point to a Def_Var instance.
* @param definition
*/
public void setDefinitions(Definition definition ) {
public void setDefinitions(Definition definition) {
if (getterStatementBlock != null) {
getterStatementBlock.setMyDefinition(definition);
}
......@@ -391,4 +413,36 @@ public final class Property_Type extends Type {
public boolean isInternal() {
return isInternal;
}
public boolean isAutoProperty() {
return isAutoProperty;
}
/**
* Generates the statement blocks for auto properties.
* @param definition Definition of specific property. It should point to a Def_Var instance.
*/
public void generateAutoProperty(Definition definition) {
if (!isAutoProperty) {
return;
}
final VisibilityModifier vm = definition.getVisibilityModifier();
final Reference valueRef = new Reference(null, Reference.Ref_Type.REF_VALUE);
final Identifier valueId = new Identifier(Identifier_type.ID_TTCN, "value", null);
final FieldSubReference valueSubReference = new FieldSubReference(valueId);
valueRef.addSubReference(valueSubReference);
final Reference thisRef = new Reference(definition.getIdentifier(), Ref_Type.REF_BASIC);
final FieldSubReference thisSubReference = new FieldSubReference(definition.getIdentifier());
thisRef.addSubReference(thisSubReference);
final TTCN3Template temp = new SpecificValue_Template(new Referenced_Value(thisRef));
final TTCN3Template tempValue = new SpecificValue_Template(new Referenced_Value(valueRef));
final Assignment_Statement ass = new Assignment_Statement(thisRef, tempValue);
setStatementBlockGetter(null, temp, vm, isAbstract, isFinal, isDeterministic, null, null);
setStatementBlockSetter(null, ass, vm, isAbstract, isFinal, isDeterministic, null, null);
}
}
......@@ -4724,6 +4724,9 @@ pr_SingleVarInstance[Type type, parameterEvaluationType eval, boolean isAbstract
$definition = new Def_Var( $i.identifier, type2, value, $eval );
$definition.setLocation(getLocation( $start, getLastVisibleToken()));
if (isProperty) {
if (((Property_Type)type2).isAutoProperty()) {
((Property_Type)type2).generateAutoProperty($definition);
}
((Property_Type)type2).setDefinitions($definition);
}
}
......@@ -9653,12 +9656,12 @@ pr_PropertyBody[Type type, boolean isAbstract, boolean isFinal, boolean isDeterm
$sbg1.visibilityLocation, $sbg1.modifierLocation );
}
( sbs1 = pr_PropertySetter {
$prop.setStatementBlockSetter( $sbs1.statementblock, $sbs1.template, $sbs1.visibility,
$prop.setStatementBlockSetter( $sbs1.statementblock, $sbs1.assignment, $sbs1.visibility,
$sbs1.isAbstract, $sbs1.isFinal, $sbs1.isDeterministic,
$sbs1.visibilityLocation, $sbs1.modifierLocation );
} )?
| sbs2 = pr_PropertySetter {
$prop.setStatementBlockSetter( $sbs2.statementblock, $sbs2.template, $sbs2.visibility,
$prop.setStatementBlockSetter( $sbs2.statementblock, $sbs2.assignment, $sbs2.visibility,
$sbs2.isAbstract, $sbs2.isFinal, $sbs2.isDeterministic,
$sbs2.visibilityLocation, $sbs2.modifierLocation );
}
......@@ -9701,7 +9704,7 @@ returns[StatementBlock statementblock, TTCN3Template template, VisibilityModifie
);
pr_PropertySetter
returns[StatementBlock statementblock, TTCN3Template template, VisibilityModifier visibility,
returns[StatementBlock statementblock, Assignment_Statement assignment, VisibilityModifier visibility,
boolean isAbstract, boolean isFinal, boolean isDeterministic,
Location visibilityLocation, Location modifierLocation]:
(
......@@ -9716,7 +9719,7 @@ returns[StatementBlock statementblock, TTCN3Template template, VisibilityModifie
SETKEYWORD
(
( CLASSCASTING
templ = pr_TemplateBody { $template = $templ.template; }
ass = pr_Assignment { $assignment = $ass.statement; }
| sb = pr_StatementBlock { $statementblock = $sb.statementblock; $statementblock.setLocation(getLocation($sb.start, $sb.stop)); }
)
)?
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment