Commit 8e60d3ce authored by Miklos Magyari's avatar Miklos Magyari
Browse files

OOP: synch with titan core (6) (issue #487)


Signed-off-by: Miklos Magyari's avatarMiklos Magyari <miklos.magyari@sigmatechnology.se>
parent a8db12b5
......@@ -50,6 +50,7 @@ import org.eclipse.titan.designer.AST.TTCN3.attributes.PrototypeAttribute;
import org.eclipse.titan.designer.AST.TTCN3.attributes.Qualifiers;
import org.eclipse.titan.designer.AST.TTCN3.attributes.SingleWithAttribute;
import org.eclipse.titan.designer.AST.TTCN3.attributes.SingleWithAttribute.Attribute_Type;
import org.eclipse.titan.designer.AST.TTCN3.definitions.FormalParameterList.IsIdenticalResult;
import org.eclipse.titan.designer.AST.TTCN3.statements.StatementBlock;
import org.eclipse.titan.designer.AST.TTCN3.types.ClassTypeBody;
import org.eclipse.titan.designer.AST.TTCN3.types.Class_Type;
......@@ -82,7 +83,7 @@ import org.eclipse.ui.ISharedImages;
* @author Miklos Magyari
* @author Adam Knapp
* */
public final class Def_Function extends Definition implements IParameterisedAssignment {
public final class Def_Function extends Definition implements IParameterisedAssignment, IFunctionBase {
/**
* The encoding prototype. Used with the extension attributes. Also used
* by Def_ExtFunction
......@@ -451,6 +452,7 @@ public final class Def_Function extends Definition implements IParameterisedAssi
return isAbstract;
}
@Override
public boolean isFinal() {
return isFinal;
}
......@@ -1625,6 +1627,7 @@ public final class Def_Function extends Definition implements IParameterisedAssi
this.isOverride = isOverride;
}
@Override
public Location getSignatureLocation() {
return signatureLocation;
}
......@@ -1632,4 +1635,47 @@ public final class Def_Function extends Definition implements IParameterisedAssi
public void setSignatureLocation(Location signatureLocation) {
this.signatureLocation = signatureLocation;
}
@Override
public IsIdenticalResult isIdentical(CompilationTimeStamp timestamp, IFunctionBase other) {
if (! (other instanceof Def_Function)) {
return IsIdenticalResult.RES_DIFFERS;
}
final Def_Function otherf = (Def_Function)other;
final Assignment_type asstype = getAssignmentType();
final Assignment_type asstype2 = otherf.getAssignmentType();
if (getAssignmentType() != asstype2) {
if ((asstype == Assignment_type.A_FUNCTION && asstype2 != Assignment_type.A_EXT_FUNCTION) ||
(asstype == Assignment_type.A_EXT_FUNCTION && asstype2 != Assignment_type.A_FUNCTION) ||
(asstype == Assignment_type.A_FUNCTION_RVAL && asstype2 != Assignment_type.A_EXT_FUNCTION_RVAL) ||
(asstype == Assignment_type.A_EXT_FUNCTION_RVAL && asstype2 != Assignment_type.A_FUNCTION_RVAL) ||
(asstype == Assignment_type.A_FUNCTION_RTEMP && asstype2 != Assignment_type.A_EXT_FUNCTION_RTEMP) ||
(asstype == Assignment_type.A_EXT_FUNCTION_RTEMP && asstype2 != Assignment_type.A_FUNCTION_RTEMP)) {
return IsIdenticalResult.RES_DIFFERS;
}
}
if (returnType != null && ! otherf.getType(timestamp).isIdentical(timestamp, returnType)) {
return IsIdenticalResult.RES_DIFFERS;
}
final FormalParameterList otherFpl = otherf.getFormalParameterList();
IsIdenticalResult identical = getFormalParameterList().isIdentical(timestamp, otherFpl);
if (identical == IsIdenticalResult.RES_DIFFERS) {
return IsIdenticalResult.RES_DIFFERS;
}
if (exceptions != null || otherf.exceptions != null) {
if (exceptions == null || otherf.exceptions == null) {
return IsIdenticalResult.RES_DIFFERS;
}
if (exceptions.getNofExceptions() != otherf.exceptions.getNofExceptions()) {
return IsIdenticalResult.RES_DIFFERS;
}
for (int i = 0; i < exceptions.getNofExceptions(); i++) {
if (otherf.exceptions.hasException(timestamp, exceptions.getExceptionByIndex(i))) {
return IsIdenticalResult.RES_DIFFERS;
}
}
}
return identical;
}
}
/******************************************************************************
* Copyright (c) 2000-2022 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.definitions;
import org.eclipse.titan.designer.AST.Location;
import org.eclipse.titan.designer.AST.TTCN3.definitions.FormalParameterList.IsIdenticalResult;
import org.eclipse.titan.designer.parsers.CompilationTimeStamp;
/**
* This interface represents methods used by different class member function types (normal, external, abstract)
*
* @author Miklos Magyari
*
*/
public interface IFunctionBase {
/** checks whether two functions have the same signature */
IsIdenticalResult isIdentical(CompilationTimeStamp timestamp, IFunctionBase other);
/** Checks if a function is final (cannot be overridden) */
boolean isFinal();
/** Gets the location of function signature (name and parameters) */
public Location getSignatureLocation();
}
......@@ -49,6 +49,7 @@ import org.eclipse.titan.designer.AST.TTCN3.definitions.Definitions;
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.IsIdenticalResult;
import org.eclipse.titan.designer.AST.TTCN3.definitions.IFunctionBase;
import org.eclipse.titan.designer.AST.TTCN3.definitions.IParameterisedAssignment;
import org.eclipse.titan.designer.AST.TTCN3.definitions.VisibilityModifier;
import org.eclipse.titan.designer.AST.TTCN3.statements.Assignment_Statement;
......@@ -100,6 +101,17 @@ public final class Class_Type extends Type implements ITypeWithComponents {
private static final String DIFFERSFROMOBJECTMETHOD = "The prototype of method `{0}'' is not identical " +
"to that of the method inherited from the 'object' class";
private static final String SHADOWSOBJECTMETHOD = "`{0}'' shadows a method inherited from the 'object' class";
private static final String PARAMNAMEDIFFERS = "One or more parameter names differ from previous definition";
private static final String PROTOTYPENOTIDENTICAL = "The prototype of method `{0}'' is not identical " +
"to that of inherited method `{1}''";
private static final String PROTOTYPESDIFFER = "The prototypes of methods `{0}'' inherited from " +
"classes `{1}'' and `{2}'' are not identical";
private static final String CANNOTOVERRIDEFINAL = "Cannot override final method `{0}''";
private static final String PUBLICCANBEOVERRIDDEN = "Public methods can be only overridden by public methods `{0}''";
private static final String PROTECTEDCANBEOVERRIDDEN = "Protected methods can be only overridden by " +
"public or protected methods `{0}''";
private static final String SHADOWSINHERITEDMEMBER = "`{0}'' shadows inherited member `{1}''";
private static final String SHADOWSINHERITED2 = "`{0}'' shadows inherited {1} `{2}''";
private static final String ABSTRACTCANNOTBEFINAL = "An absract class cannot be final";
private static final String TRAITCANNOTBEFINAL = "A trait class cannot be final";
......@@ -107,7 +119,7 @@ public final class Class_Type extends Type implements ITypeWithComponents {
private static final String TRAITWITHFINALLY = "A trait class should not define a finally block";
private static final String UNKNOWNFIELD = "Unknown field reference";
private static final String PRIVATEINACCESSIBLE = "Private member is inaccessible due to its protection level";
private static final String PARAMNAMEDIFFERS = "One or more parameter names differ from previous definition";
/**
* The superclass of this class
* (the only non-trait class that this class extends)
......@@ -724,21 +736,73 @@ public final class Class_Type extends Type implements ITypeWithComponents {
case A_FUNCTION_RTEMP:
case A_EXT_FUNCTION:
case A_EXT_FUNCTION_RVAL:
case A_EXT_FUNCTION_RTEMP:
Def_Function func1 = (Def_Function)def1;
Def_Function func2 = (Def_Function)def2;
break;
case A_EXT_FUNCTION_RTEMP: {
IFunctionBase func1 = (IFunctionBase)def1;
IFunctionBase func2 = (IFunctionBase)def2;
boolean func1IsAbstract = def1 instanceof Def_AbsFunction;
boolean func2IsAbstract = def2 instanceof Def_AbsFunction;
IsIdenticalResult identical = func1.isIdentical(timestamp, func2);
if (identical == IsIdenticalResult.RES_NAME_DIFFERS) {
def1.getLocation().reportSemanticWarning(PARAMNAMEDIFFERS);
}
if (def2.getVisibility() != VisibilityModifier.Private &&
(identical == IsIdenticalResult.RES_DIFFERS || func1IsAbstract != func2IsAbstract)) {
if (subclassLoc == null && identical == IsIdenticalResult.RES_DIFFERS) {
def1.getLocation().reportSemanticError(
MessageFormat.format(PROTOTYPENOTIDENTICAL, id1.getDisplayName(), def2.getFullName()));
} else if (subclassLoc != null && def1.getVisibility() != VisibilityModifier.Private) {
subclassLoc.reportSemanticError(
MessageFormat.format(PROTOTYPESDIFFER, id1.getDisplayName(), c1.getIdentifier().getDisplayName(),
c2.getIdentifier().getDisplayName()));
}
} else if (subclassLoc == null && func2.isFinal()) {
func1.getSignatureLocation().reportSemanticError(
MessageFormat.format(CANNOTOVERRIDEFINAL, def2.getFullName()));
} else if (subclassLoc == null && func1.isIdentical(timestamp, func2) != IsIdenticalResult.RES_DIFFERS) {
if (def2.getVisibility() == VisibilityModifier.Public && def1.getVisibility() != VisibilityModifier.Public) {
func1.getSignatureLocation().reportSemanticError(
MessageFormat.format(PUBLICCANBEOVERRIDDEN, id1.getDisplayName()));
} else if (def2.getVisibility() == VisibilityModifier.Protected &&
def1.getVisibility() != VisibilityModifier.Public && def1.getVisibility() != VisibilityModifier.Protected) {
func1.getSignatureLocation().reportSemanticError(
MessageFormat.format(PROTECTEDCANBEOVERRIDDEN, id1.getDisplayName()));
}
}
break; }
default:
break;
def1.getLocation().reportSemanticError(
MessageFormat.format(SHADOWSINHERITEDMEMBER, def1.getDescription(), def2.getFullName()));
nameClash = true;
break;
}
break;
default:
def1.getLocation().reportSemanticError(
MessageFormat.format(SHADOWSINHERITED2, def1.getDescription(),
(def2 instanceof IFunctionBase) ? "method" : "member",
def2.getFullName()));
nameClash = true;
break;
}
}
}
if (subclassLoc != null) {
// the code above only goes through the local members of c1,
// comparing them to local or inherited members of c2;
// the members in the superclass and supertraits of c1 must also be compared to c2
if (c1.baseClass != null) {
nameClash |= compareMembers(c1.baseClass, c2, subclassLoc, timestamp);
}
if (c1.baseTraits != null) {
for (int i = 0; i < c1.baseTraits.getNofTypes(); i++) {
Type baseTrait = c1.baseTraits.getType(i);
if (baseTrait != null) {
Class_Type baseTraitClass = baseTrait.getTypeRefdLast(timestamp).getClassTypeBody();
nameClash |= compareMembers(baseTraitClass, c2, subclassLoc, timestamp);
}
}
}
}
return nameClash;
}
......
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