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; ...@@ -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.GovernedSimple.CodeSectionType;
import org.eclipse.titan.designer.AST.INamedNode; import org.eclipse.titan.designer.AST.INamedNode;
import org.eclipse.titan.designer.AST.IType; 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.IType.ValueCheckingOptions;
import org.eclipse.titan.designer.AST.IValue; import org.eclipse.titan.designer.AST.IValue;
import org.eclipse.titan.designer.AST.ReferenceFinder; import org.eclipse.titan.designer.AST.ReferenceFinder;
...@@ -59,7 +58,6 @@ public final class Return_Statement extends Statement { ...@@ -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 INVALIDRETURNINDYNAMICTEMPLATESB2 = "A specific value without matching symbols was expected as return value";
private static final String FULLNAMEPART = ".returnexpression"; private static final String FULLNAMEPART = ".returnexpression";
private static final String STATEMENT_NAME = "return"; private static final String STATEMENT_NAME = "return";
private static final String RETURNTYPEEXPECTED = "Return type `{0}'' expected";
private final TTCN3Template template; private final TTCN3Template template;
private boolean genRestrictionCheck = false; private boolean genRestrictionCheck = false;
...@@ -194,18 +192,21 @@ public final class Return_Statement extends Statement { ...@@ -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); final IType propType = property.getFieldType(timestamp, null, 0, Expected_Value_type.EXPECTED_DYNAMIC_VALUE, false);
location.reportSemanticError(MessageFormat.format(MISSINGTEMPLATE, propType.getTypename())); location.reportSemanticError(MessageFormat.format(MISSINGTEMPLATE, propType.getTypename()));
} else { } 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); 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()) { if (myStatementBlock.isPropertySetter()) {
location.reportSemanticError(INVALIDSETTERRETURN); location.reportSemanticError(INVALIDSETTERRETURN);
return; break;
} }
} }
break; break;
......
...@@ -14,12 +14,14 @@ import java.util.List; ...@@ -14,12 +14,14 @@ import java.util.List;
import org.eclipse.titan.designer.AST.Assignment; import org.eclipse.titan.designer.AST.Assignment;
import org.eclipse.titan.designer.AST.Assignment.Assignment_type; 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.IReferenceChain;
import org.eclipse.titan.designer.AST.IType; import org.eclipse.titan.designer.AST.IType;
import org.eclipse.titan.designer.AST.Identifier; import org.eclipse.titan.designer.AST.Identifier;
import org.eclipse.titan.designer.AST.Identifier.Identifier_type; import org.eclipse.titan.designer.AST.Identifier.Identifier_type;
import org.eclipse.titan.designer.AST.Location; import org.eclipse.titan.designer.AST.Location;
import org.eclipse.titan.designer.AST.Reference; 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.ReferenceChain;
import org.eclipse.titan.designer.AST.Scope; import org.eclipse.titan.designer.AST.Scope;
import org.eclipse.titan.designer.AST.Type; import org.eclipse.titan.designer.AST.Type;
...@@ -30,10 +32,14 @@ import org.eclipse.titan.designer.AST.TTCN3.definitions.Definition; ...@@ -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.FormalParameter;
import org.eclipse.titan.designer.AST.TTCN3.definitions.FormalParameterList; 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.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;
import org.eclipse.titan.designer.AST.TTCN3.statements.StatementBlock.ReturnStatus_type; 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.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.templates.TTCN3Template;
import org.eclipse.titan.designer.AST.TTCN3.values.Referenced_Value;
import org.eclipse.titan.designer.compiler.JavaGenData; import org.eclipse.titan.designer.compiler.JavaGenData;
import org.eclipse.titan.designer.parsers.CompilationTimeStamp; import org.eclipse.titan.designer.parsers.CompilationTimeStamp;
...@@ -42,7 +48,6 @@ import org.eclipse.titan.designer.parsers.CompilationTimeStamp; ...@@ -42,7 +48,6 @@ import org.eclipse.titan.designer.parsers.CompilationTimeStamp;
* *
* @author Miklos Magyari * @author Miklos Magyari
* */ * */
public final class Property_Type extends Type { 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 INITIALVALUEWITHOUTSETTER = "A property without a setter cannot have an initial value";
private static final String EMPTYBODY = "An empty property body is not allowed"; private static final String EMPTYBODY = "An empty property body is not allowed";
...@@ -51,6 +56,9 @@ public final class Property_Type extends Type { ...@@ -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 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 ABSTRACTWITHBODY = "Abstract {0} should not have a body";
private static final String GETTER = "getter";
private static final String SETTER = "setter";
/** type of the property */ /** type of the property */
private Type myType; private Type myType;
...@@ -64,7 +72,7 @@ public final class Property_Type extends Type { ...@@ -64,7 +72,7 @@ public final class Property_Type extends Type {
private TTCN3Template getterTemplate; private TTCN3Template getterTemplate;
/** template definition of the property setter, if defined */ /** template definition of the property setter, if defined */
private TTCN3Template setterTemplate; private Assignment_Statement setterAssignment;
/** a template containing the initial value for the property */ /** a template containing the initial value for the property */
private TTCN3Template initValTemplate; private TTCN3Template initValTemplate;
...@@ -107,7 +115,7 @@ public final class Property_Type extends Type { ...@@ -107,7 +115,7 @@ public final class Property_Type extends Type {
this.setterStatementBlock = null; this.setterStatementBlock = null;
this.getterStatementBlock = null; this.getterStatementBlock = null;
this.setterTemplate = null; this.setterAssignment = null;
this.getterTemplate = null; this.getterTemplate = null;
this.initValTemplate = null; this.initValTemplate = null;
this.isAutoProperty = true; this.isAutoProperty = true;
...@@ -123,8 +131,15 @@ public final class Property_Type extends Type { ...@@ -123,8 +131,15 @@ public final class Property_Type extends Type {
} }
/** /**
* Sets the statement block for the property getter * Sets the statement block for the property setter. If it is {@code null} it generates one.
* @param sb * @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, public void setStatementBlockGetter(StatementBlock sb, TTCN3Template template, VisibilityModifier modifier,
boolean isAbstract, boolean isFinal, boolean isDeterministic, boolean isAbstract, boolean isFinal, boolean isDeterministic,
...@@ -137,20 +152,34 @@ public final class Property_Type extends Type { ...@@ -137,20 +152,34 @@ public final class Property_Type extends Type {
isGetterDeterministic = isDeterministic; isGetterDeterministic = isDeterministic;
getterVisibilityLocation = visibilityLocation; getterVisibilityLocation = visibilityLocation;
getterModifierLocation = modifierLocation; 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) { if (getterStatementBlock != null) {
getterStatementBlock.setIsGetter(); getterStatementBlock.setIsGetter();
getterStatementBlock.setOwnerIsProperty(); getterStatementBlock.setOwnerIsProperty();
getterStatementBlock.setFullNameParent(this); getterStatementBlock.setFullNameParent(this);
} }
getterTemplate = template;
} }
/** /**
* Sets the statement block for the property setter * Sets the statement block for the property setter. If it is {@code null} it generates one.
* @param sb * @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, boolean isAbstract, boolean isFinal, boolean isDeterministic,
Location visibilityLocation, Location modifierLocation) { Location visibilityLocation, Location modifierLocation) {
hasSetter = true; hasSetter = true;
...@@ -160,13 +189,18 @@ public final class Property_Type extends Type { ...@@ -160,13 +189,18 @@ public final class Property_Type extends Type {
isSetterDeterministic = isDeterministic; isSetterDeterministic = isDeterministic;
setterVisibilityLocation = visibilityLocation; setterVisibilityLocation = visibilityLocation;
setterModifierLocation = modifierLocation; setterModifierLocation = modifierLocation;
setterAssignment = assignment;
if (setterStatementBlock == null && setterAssignment != null) {
setterStatementBlock = new StatementBlock();
setterStatementBlock.addStatement(setterAssignment);
}
if (setterStatementBlock != null) { if (setterStatementBlock != null) {
setterStatementBlock.setIsSetter(); setterStatementBlock.setIsSetter();
setterStatementBlock.setOwnerIsProperty(); setterStatementBlock.setOwnerIsProperty();
setterStatementBlock.setFullNameParent(this); setterStatementBlock.setFullNameParent(this);
} }
setterTemplate = template;
} }
@Override @Override
...@@ -178,7 +212,7 @@ public final class Property_Type extends Type { ...@@ -178,7 +212,7 @@ public final class Property_Type extends Type {
lastTimeChecked = timestamp; lastTimeChecked = timestamp;
if (hasBody == true && hasGetter() == false && hasSetter() == false) { if (hasBody && !hasGetter() && !hasSetter()) {
getLocation().reportSemanticError(EMPTYBODY); getLocation().reportSemanticError(EMPTYBODY);
} }
...@@ -194,7 +228,7 @@ public final class Property_Type extends Type { ...@@ -194,7 +228,7 @@ public final class Property_Type extends Type {
setterStatementBlock.setValueParamList(fpList); setterStatementBlock.setValueParamList(fpList);
setterStatementBlock.check(timestamp); setterStatementBlock.check(timestamp);
} }
if (initValTemplate != null && hasSetter() == false) { if (initValTemplate != null && !hasSetter()) {
initValTemplate.getLocation().reportSemanticError(INITIALVALUEWITHOUTSETTER); initValTemplate.getLocation().reportSemanticError(INITIALVALUEWITHOUTSETTER);
initValTemplate.setIsErroneous(true); initValTemplate.setIsErroneous(true);
} }
...@@ -211,24 +245,20 @@ public final class Property_Type extends Type { ...@@ -211,24 +245,20 @@ public final class Property_Type extends Type {
if (isGetterAbstract) { if (isGetterAbstract) {
if (isGetterFinal) { if (isGetterFinal) {
getterModifierLocation.reportSemanticError(MessageFormat.format( getterModifierLocation.reportSemanticError(MessageFormat.format(MODIFIERFINALABSTRACT, GETTER));
MODIFIERFINALABSTRACT, "getter"));
} }
if (getterStatementBlock != null || getterTemplate != null) { if (getterStatementBlock != null || getterTemplate != null) {
final Location getterLoc = getterStatementBlock == null ? getterTemplate.getLocation() : getterStatementBlock.getLocation(); final Location getterLoc = getterStatementBlock == null ? getterTemplate.getLocation() : getterStatementBlock.getLocation();
getterLoc.reportSemanticError(MessageFormat.format( getterLoc.reportSemanticError(MessageFormat.format(ABSTRACTWITHBODY, GETTER));
ABSTRACTWITHBODY, "getter"));
} }
} }
if (isSetterAbstract) { if (isSetterAbstract) {
if (isSetterFinal) { if (isSetterFinal) {
setterModifierLocation.reportSemanticError(MessageFormat.format( setterModifierLocation.reportSemanticError(MessageFormat.format(MODIFIERFINALABSTRACT, SETTER));
MODIFIERFINALABSTRACT, "setter"));
} }
if (setterStatementBlock != null || setterTemplate != null) { if (setterStatementBlock != null || setterAssignment != null) {
final Location setterLoc = setterStatementBlock == null ? setterTemplate.getLocation() : setterStatementBlock.getLocation(); final Location setterLoc = setterStatementBlock == null ? setterAssignment.getLocation() : setterStatementBlock.getLocation();
setterLoc.reportSemanticError(MessageFormat.format( setterLoc.reportSemanticError(MessageFormat.format(ABSTRACTWITHBODY, SETTER));
ABSTRACTWITHBODY, "setter"));
} }
} }
} }
...@@ -264,22 +294,14 @@ public final class Property_Type extends Type { ...@@ -264,22 +294,14 @@ public final class Property_Type extends Type {
* @return * @return
*/ */
public boolean hasSetter() { public boolean hasSetter() {
if (isAutoProperty) { return isAutoProperty ? true : hasSetter;
return true;
}
return hasSetter;
} }
/** Checks whether the property has a getter definition /** Checks whether the property has a getter definition
* @return * @return
*/ */
public boolean hasGetter() { public boolean hasGetter() {
if (isAutoProperty) { return isAutoProperty ? true : hasGetter;
return true;
}
return hasGetter;
} }
public void setInitValTemplate(TTCN3Template template) { public void setInitValTemplate(TTCN3Template template) {
...@@ -375,11 +397,11 @@ public final class Property_Type extends Type { ...@@ -375,11 +397,11 @@ public final class Property_Type extends Type {
return null; 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 * @param definition
*/ */
public void setDefinitions(Definition definition ) { public void setDefinitions(Definition definition) {
if (getterStatementBlock != null) { if (getterStatementBlock != null) {
getterStatementBlock.setMyDefinition(definition); getterStatementBlock.setMyDefinition(definition);
} }
...@@ -391,4 +413,36 @@ public final class Property_Type extends Type { ...@@ -391,4 +413,36 @@ public final class Property_Type extends Type {
public boolean isInternal() { public boolean isInternal() {
return 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 ...@@ -4724,6 +4724,9 @@ pr_SingleVarInstance[Type type, parameterEvaluationType eval, boolean isAbstract
$definition = new Def_Var( $i.identifier, type2, value, $eval ); $definition = new Def_Var( $i.identifier, type2, value, $eval );
$definition.setLocation(getLocation( $start, getLastVisibleToken())); $definition.setLocation(getLocation( $start, getLastVisibleToken()));
if (isProperty) { if (isProperty) {
if (((Property_Type)type2).isAutoProperty()) {
((Property_Type)type2).generateAutoProperty($definition);
}
((Property_Type)type2).setDefinitions($definition); ((Property_Type)type2).setDefinitions($definition);
} }
} }
...@@ -9653,12 +9656,12 @@ pr_PropertyBody[Type type, boolean isAbstract, boolean isFinal, boolean isDeterm ...@@ -9653,12 +9656,12 @@ pr_PropertyBody[Type type, boolean isAbstract, boolean isFinal, boolean isDeterm
$sbg1.visibilityLocation, $sbg1.modifierLocation ); $sbg1.visibilityLocation, $sbg1.modifierLocation );
} }
( sbs1 = pr_PropertySetter { ( 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.isAbstract, $sbs1.isFinal, $sbs1.isDeterministic,
$sbs1.visibilityLocation, $sbs1.modifierLocation ); $sbs1.visibilityLocation, $sbs1.modifierLocation );
} )? } )?
| sbs2 = pr_PropertySetter { | 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.isAbstract, $sbs2.isFinal, $sbs2.isDeterministic,
$sbs2.visibilityLocation, $sbs2.modifierLocation ); $sbs2.visibilityLocation, $sbs2.modifierLocation );
} }
...@@ -9701,7 +9704,7 @@ returns[StatementBlock statementblock, TTCN3Template template, VisibilityModifie ...@@ -9701,7 +9704,7 @@ returns[StatementBlock statementblock, TTCN3Template template, VisibilityModifie
); );
pr_PropertySetter pr_PropertySetter
returns[StatementBlock statementblock, TTCN3Template template, VisibilityModifier visibility, returns[StatementBlock statementblock, Assignment_Statement assignment, VisibilityModifier visibility,
boolean isAbstract, boolean isFinal, boolean isDeterministic, boolean isAbstract, boolean isFinal, boolean isDeterministic,
Location visibilityLocation, Location modifierLocation]: Location visibilityLocation, Location modifierLocation]:
( (
...@@ -9716,7 +9719,7 @@ returns[StatementBlock statementblock, TTCN3Template template, VisibilityModifie ...@@ -9716,7 +9719,7 @@ returns[StatementBlock statementblock, TTCN3Template template, VisibilityModifie
SETKEYWORD SETKEYWORD
( (
( CLASSCASTING ( 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)); } | 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