Commit 3debb528 authored by Miklos Magyari's avatar Miklos Magyari
Browse files

OOP: synch with titan core (1)


Signed-off-by: Miklos Magyari's avatarMiklos Magyari <miklos.magyari@sigmatechnology.se>
parent ac5969e1
/******************************************************************************
* Copyright (c) 2000-2021 Ericsson Telecom AB
* 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
......@@ -12,12 +12,14 @@ import java.util.List;
import org.eclipse.titan.designer.AST.ASTNode;
import org.eclipse.titan.designer.AST.ASTVisitor;
import org.eclipse.titan.designer.AST.Scope;
import org.eclipse.titan.designer.AST.Type;
/**
* Type list used in port types to store attributes.
* Type list used in port types to store attributes and in classes to store traits
*
* @author Kristof Szabados
* @author Miklos Magyari
* */
public final class Types extends ASTNode {
......@@ -27,9 +29,13 @@ public final class Types extends ASTNode {
types = new ArrayList<Type>();
}
public void addType(final Type type) {
public synchronized void addType(final Type type) {
types.add(type);
}
public synchronized Type extractTypeByIndex(final int index) {
return types.remove(index);
}
public int getNofTypes() {
return types.size();
......@@ -51,4 +57,12 @@ public final class Types extends ASTNode {
}
return true;
}
@Override
/** {@inheritDoc} */
public void setMyScope(final Scope scope) {
for (Type type : types) {
type.setMyScope(scope);
}
}
}
......@@ -8,6 +8,7 @@
package org.eclipse.titan.designer.AST.TTCN3.types;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
......@@ -35,6 +36,7 @@ import org.eclipse.titan.designer.AST.TypeCompatibilityInfo.Chain;
import org.eclipse.titan.designer.AST.Value;
import org.eclipse.titan.designer.AST.TTCN3.Expected_Value_type;
import org.eclipse.titan.designer.AST.TTCN3.TemplateRestriction.Restriction_type;
import org.eclipse.titan.designer.AST.TTCN3.attributes.Types;
import org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Const;
import org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Function;
import org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Template;
......@@ -62,6 +64,19 @@ import org.eclipse.titan.designer.parsers.ttcn3parser.TTCN3ReparseUpdater;
* @author Miklos Magyari
* */
public final class Class_Type extends Type implements ITypeWithComponents {
private static final String ONLYONEMODIFIER = "A class cannot have more than one of the @final, @abstract and @trait modifiers";
private static final String EXTERNALABSTRACT = "External classes cannot be abstract";
private static final String CLASSEXPECTED = "Class type expected instead of `{0}''";
private static final String TRAITEXTENDTRAIT = "A trait class cannot extend a non-trait class";
private static final String CANNOTEXTENDMORETHANONE = "A class cannot extend more than one non-trait class";
private static final String PREVEXTENDED = "Previous extended non-trait class is here";
private static final String BASECANNOTBEFINAL = "The superclass cannot be final";
private static final String EXTERNALEXTENDINTERNAL = "An external class cannot extend an internal class";
private static final String DUPLICATECLASSTYPE = "Duplicate class type in list of classes being extended";
private static final String RUNSONINCOMPATIBLE = "The `runs on' component type of the subclass, `{0}'', is not compatible with the `runs on' component type of the superclass, `{1}''";
private static final String MTCINCOMPATIBLE = "The `mtc' component type of the subclass, `{0}'', is not compatible with the `runs on' component type of the superclass, `{1}''";
private static final String SYSTEMINCOMPATIBLE = "The `system' component type of the subclass, `{0}'', is not compatible with the `runs on' component type of the superclass, `{1}''";
private static final String ABSTRACTCANNOTBEFINAL = "An absract class cannot be final";
private static final String TRAITCANNOTBEFINAL = "A trait class cannot be final";
private static final String ABSTRACTCANNOTBETRAIT = "A class cannot be both abstract and trait";
......@@ -77,6 +92,7 @@ public final class Class_Type extends Type implements ITypeWithComponents {
private final ClassTypeBody classBody;
private boolean isBuiltIn;
private final boolean isAbstract;
private final boolean isFinal;
private final boolean isTrait;
......@@ -92,13 +108,17 @@ public final class Class_Type extends Type implements ITypeWithComponents {
private Component_Type mtcType;
private Component_Type systemType;
private Types baseTraits;
private Type baseType;
private Class_Type baseClass;
public enum ClassRelation {
Identical, Related, Unrelated
}
public Class_Type(ClassTypeBody classBody, boolean isAbstract, boolean isFinal, boolean isTrait, boolean isExternal,
Location modifierLocation, final Reference runsOnRef, final Reference mtcRef, final Reference systemRef,
ClassTypeReferenceList refs, StatementBlock finallyBlock) {
ClassTypeReferenceList refs, Types baseTraits, StatementBlock finallyBlock) {
this.classBody = classBody;
this.isAbstract = isAbstract;
......@@ -111,6 +131,7 @@ public final class Class_Type extends Type implements ITypeWithComponents {
this.mtcRef = mtcRef;
this.systemRef = systemRef;
this.refs = refs;
this.baseTraits = baseTraits;
if (classBody != null) {
classBody.setFullNameParent(this);
......@@ -125,6 +146,9 @@ public final class Class_Type extends Type implements ITypeWithComponents {
if (systemRef != null) {
systemRef.setFullNameParent(this);
}
if (baseTraits != null) {
baseTraits.setFullNameParent(this);
}
if (finallyBlock != null) {
finallyBlock.setFullNameParent(this);
finallyBlock.setOwnerIsFinally();
......@@ -132,10 +156,10 @@ public final class Class_Type extends Type implements ITypeWithComponents {
}
/**
* constructor used for classes defined using the 'object' keyword
* constructor used for classes defined using the 'object' keyword
*/
public Class_Type() {
this(null, true, false, false, false, null, null, null, null, null, null);
this(null, true, false, false, false, null, null, null, null, null, null, null);
}
@Override
......@@ -175,6 +199,9 @@ public final class Class_Type extends Type implements ITypeWithComponents {
if (systemRef != null) {
systemRef.setMyScope(scope);
}
if (baseTraits != null) {
baseTraits.setMyScope(scope);
}
}
@Override
......@@ -263,31 +290,99 @@ public final class Class_Type extends Type implements ITypeWithComponents {
return;
}
if (refs != null) {
for (Reference ref : refs.getReferenceList()) {
final Assignment assignment = ref.getRefdAssignment(timestamp, false);
if (assignment != null) {
final IType type = assignment.getType(timestamp);
if (type instanceof Class_Type) {
final Class_Type parent = (Class_Type)type;
if (parent.isTrait == false) {
superClass = parent;
if (isBuiltIn) {
return;
}
if ((isFinal && isAbstract) || (isFinal && isTrait) || (isAbstract && isTrait)) {
modifierLocation.reportSemanticError(ONLYONEMODIFIER);
}
if (isExternal && isAbstract) {
modifierLocation.reportSemanticError(EXTERNALABSTRACT);
}
if (baseTraits != null) {
for (int i = 0; i < baseTraits.getNofTypes(); i++) {
Type t = baseTraits.getType(i);
t.check(timestamp);
if (!(t.getTypeRefdLast(timestamp) instanceof Class_Type)) {
if (! t.getIsErroneous(timestamp)) {
t.getLocation().reportSemanticError(
MessageFormat.format(CLASSEXPECTED, t.getTypename()));
}
baseTraits.extractTypeByIndex(i);
} else {
final Class_Type tClass = (Class_Type)t.getTypeRefdLast(timestamp);
if (! tClass.isTrait) {
if (isTrait) {
t.getLocation().reportSemanticError(TRAITEXTENDTRAIT);
} else if (baseClass != null){
t.getLocation().reportSemanticError(CANNOTEXTENDMORETHANONE);
// baseClass.getLocation().reportSemanticError(PREVEXTENDED);
} else {
baseTraits.extractTypeByIndex(i);
baseType = t;
baseClass = tClass;
if (baseClass.isFinal) {
baseClass.getLocation().reportSemanticError(BASECANNOTBEFINAL);
}
if (isExternal && ! baseClass.isExternal) {
baseClass.getLocation().reportSemanticError(EXTERNALEXTENDINTERNAL);
}
}
}
for (int j = 0; j < i; j++) {
final Type t2 = baseTraits.getType(j);
if (t2 != null && t2.getTypename().equals(t.getTypename())) {
t.getLocation().reportSemanticError(DUPLICATECLASSTYPE);
}
}
}
}
}
runsOnType = null;
mtcType = null;
systemType = null;
if (baseClass != null && baseClass.isBuiltIn) {
// if the base class is 'object', then just delete it and set it to NULL,
// so it functions the same way as not specifying a base class
baseClass = null;
baseType = null;
}
if (runsOnRef != null) {
runsOnType = runsOnRef.chkComponentypeReference(timestamp);
final Component_Type runsOnType = runsOnRef.chkComponentypeReference(timestamp);
if (baseClass != null) {
final Component_Type baseRunsOnType = baseClass.getRunsOnType(timestamp);
if (baseRunsOnType != null && ! baseRunsOnType.isCompatible(timestamp, runsOnType, null , null, null)) {
runsOnRef.getLocation().reportSemanticError(
MessageFormat.format(RUNSONINCOMPATIBLE, runsOnType.getTypename(), baseRunsOnType.getTypename()));
}
}
} else if (baseClass != null) {
runsOnType = baseClass.getRunsOnType(timestamp);
}
if (mtcRef != null) {
mtcType = mtcRef.chkComponentypeReference(timestamp);
final Component_Type mtcType = mtcRef.chkComponentypeReference(timestamp);
if (baseClass != null) {
final Component_Type baseMtcType = baseClass.getMtcType(timestamp);
if (baseMtcType != null && ! baseMtcType.isCompatible(timestamp, mtcType, null , null, null)) {
mtcRef.getLocation().reportSemanticError(
MessageFormat.format(MTCINCOMPATIBLE, mtcType.getTypename(), baseMtcType.getTypename()));
}
}
} else if (baseClass != null) {
mtcType = baseClass.getMtcType(timestamp);
}
if (systemRef != null) {
systemType = systemRef.chkComponentypeReference(timestamp);
final Component_Type systemType = systemRef.chkComponentypeReference(timestamp);
if (baseClass != null) {
final Component_Type baseSystemType = baseClass.getSystemType(timestamp);
if (baseSystemType != null && ! baseSystemType.isCompatible(timestamp, systemType, null , null, null)) {
systemRef.getLocation().reportSemanticError(
MessageFormat.format(SYSTEMINCOMPATIBLE, systemType.getTypename(), baseSystemType.getTypename()));
}
}
} else if (baseClass != null) {
systemType = baseClass.getSystemType(timestamp);
}
if (isAbstract && isFinal) {
......
......@@ -9328,6 +9328,7 @@ pr_ClassTypeDef returns[Def_Type def_type]
Configuration_Helper systemspecHelper = new Configuration_Helper();
ClassTypeBody body = null;
ClassTypeReferenceList refs = null;
Types types = null;
VisibilityModifier visibility = VisibilityModifier.Protected;
Location modifierLocation = null;
boolean isAbstract = false;
......@@ -9348,6 +9349,7 @@ pr_ClassTypeDef returns[Def_Type def_type]
ecd = pr_ExtendsClassDef {
refs = $ecd.refList;
refs.setLocation(getLocation( $ecd.start, $ecd.stop ));
types = $ecd.baseTypes;
}
(runson = pr_RunsOnSpec[runsonHelper] {
if (runsonHelper.runsonReference != null) {
......@@ -9379,7 +9381,7 @@ pr_ClassTypeDef returns[Def_Type def_type]
if (body == null) {
body = new ClassTypeBody($i.identifier, refs);
}
Class_Type type = new Class_Type(body, isAbstract, isFinal, isTrait, isExternal, modifierLocation, runsonHelper.runsonReference, mtcHelper.mtcReference, systemspecHelper.systemReference, refs, finallyBlock);
Class_Type type = new Class_Type(body, isAbstract, isFinal, isTrait, isExternal, modifierLocation, runsonHelper.runsonReference, mtcHelper.mtcReference, systemspecHelper.systemReference, refs, types, finallyBlock);
type.setLocation(getLocation($start, getLastVisibleToken()));
$def_type = new Def_Type($i.identifier, type);
$def_type.setLocation(getLocation($kw.start, $i.stop));
......@@ -9419,18 +9421,55 @@ pr_AbstractModifier returns[boolean isAbstract]
ABSTRACTKEYWORD { $isAbstract = true; }
;
pr_ExtendsClassDef returns[ClassTypeReferenceList refList]
pr_ExtendsClassDef returns[ClassTypeReferenceList refList, Types baseTypes]
@init {
$refList = new ClassTypeReferenceList();
$baseTypes = new Types();
}:
(
EXTENDS
( ec = pr_ExtendsClassItem { if ($ec.reference != null) $refList.addReference($ec.reference); }
| OBJECTKEYWORD { } // left empty on purpose
)
( COMMA ec2 = pr_ExtendsClassItem { if ($ec2.reference != null) $refList.addReference($ec2.reference); } )*
EXTENDS
bcl = pr_BaseClassList { $baseTypes = $bcl.baseTypes; }
// ( ec = pr_ExtendsClassItem {
// if ($ec.reference != null) {
// $refList.addReference($ec.reference);
// }
// Class_Type type = new Class_Type();
// type.setLocation(getLocation($ec.start, $ec.stop));
// $baseTypes.addType(type);
// }
// | OBJECTKEYWORD { } // left empty on purpose
// )
// ( COMMA ec2 = pr_ExtendsClassItem {
// if ($ec2.reference != null) {
// $refList.addReference($ec2.reference);
// }
// Class_Type type = new Class_Type();
// type.setLocation(getLocation($ec.start, $ec.stop));
// $baseTypes.addType(type);
// }
// )*
)?;
pr_BaseClassList returns[Types baseTypes]
@init {
$baseTypes = new Types();
}:
(
(
rt = pr_ReferencedType {
$rt.type.setLocation(getLocation($rt.start, $rt.stop));
$baseTypes.addType($rt.type); }
| OBJECTKEYWORD { $baseTypes.addType(new Class_Type()); }
)
(
COMMA
(
rt2 = pr_Type { $baseTypes.addType($rt2.type); }
| OBJECTKEYWORD { $baseTypes.addType(new Class_Type()); }
)
)*
);
pr_ExtendsClassItem returns[Reference reference]
@init {
$reference = new Reference(null);
......@@ -9709,7 +9748,7 @@ pr_ClassCastingOp returns[ClassCastingExpression value]
}:
( var = pr_VariableRef { reference = $var.reference; }
CLASSCASTING
( type = pr_ReferencedType { type = $type.type; }
( type = pr_ReferencedType{ type = $type.type; }
| obj = pr_ObjectKeyword {
type = new Class_Type();
type.setLocation(getLocation($obj.start, $obj.stop));
......
......@@ -26,7 +26,7 @@ import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
Designer_plugin_tests.class,
Designer_plugin_tests_with_OOP.class
//Designer_plugin_tests_with_OOP.class
})
public final class MainTestSuite {
......
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