/**
*
* OOAS Compiler (Deprecated)
*
* Copyright 2015, Institute for Software Technology, Graz University of
* Technology. Portions are copyright 2015 by the AIT Austrian Institute
* of Technology. All rights reserved.
*
* SEE THE "LICENSE" FILE FOR THE TERMS UNDER WHICH THIS FILE IS PROVIDED.
*
* Please notice that this version of the OOAS compiler is considered de-
* precated. Only the Java version is maintained.
*
* Contributors:
* Willibald Krenn (TU Graz/AIT)
* Stefan Tiran (TU Graz/AIT)
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace TUG.Mogentes
{
///
/// Replaces all Opaque types (types we could not resolve in the first run of the parser)
/// with the resolved ones. Note: The actual resolving has already been done, i.e., the
/// resolvedType member is already set to the correct value. Now we just want to get an
/// AST that does not contain any OpaqueTypeNodes at all.
///
public sealed class OoaReplaceOpaqueVisitor : OoaCompleteAstTraversalVisitor
{
private void ReplaceOpaque(IAst parent)
{
switch (parent.nodeType)
{
case AstNodeTypeEnum.type:
ReplaceOpaqueInType((UlyssesType)parent);
break;
case AstNodeTypeEnum.identifier:
ReplaceOpaqueInIdentifier((Identifier)parent);
break;
case AstNodeTypeEnum.expression:
ReplaceOpaqueInExpression((Expression)parent);
break;
default:
throw new NotImplementedException();
}
}
private void ReplaceOpaqueInExpression(Expression expression)
{
switch (expression.kind)
{
case ExpressionKind.ObjectConstr:
ObjectConstructor c = (ObjectConstructor)expression;
c.SetType(((OpaqueType)c.type).resolvedType);
break;
case ExpressionKind.Cast:
UnaryOperator unop = (UnaryOperator)expression;
unop.SetType(((OpaqueType)unop.type).resolvedType);
break;
default:
throw new NotImplementedException();
}
}
private void ReplaceOpaqueInIdentifier(Identifier identifier)
{
switch (identifier.kind)
{
case IdentifierKind.AttributeIdentifier:
AttributeIdentifier id = (AttributeIdentifier)identifier;
System.Diagnostics.Debug.Assert(id.type is OpaqueType); // that's why we are here
id.SetType(((OpaqueType)id.type).resolvedType);
break;
case IdentifierKind.ExpressionVariableIdentifier:
ExpressionVariableIdentifier exprvar = (ExpressionVariableIdentifier)identifier;
System.Diagnostics.Debug.Assert(exprvar.type is OpaqueType);
exprvar.SetType(((OpaqueType)exprvar.type).resolvedType);
break;
case IdentifierKind.LocalVariableIdentifier:
LocalVariableIdentifier var = (LocalVariableIdentifier)identifier;
System.Diagnostics.Debug.Assert(var.type is OpaqueType);
var.SetType(((OpaqueType)var.type).resolvedType);
break;
case IdentifierKind.ParameterIdentifier:
ParameterIdentifier param = (ParameterIdentifier)identifier;
System.Diagnostics.Debug.Assert(param.type is OpaqueType);
param.SetType(((OpaqueType)identifier.type).resolvedType);
break;
default:
throw new NotImplementedException();
}
}
private void ReplaceOpaqueInType(UlyssesType ulyssesType)
{
switch (ulyssesType.kind)
{
case TypeKind.FunctionType:
FunctionType func = (FunctionType)ulyssesType;
if (func.returnType is OpaqueType)
func.SetReturnType(((OpaqueType)func.returnType).resolvedType);
LinkedListNode item = func.parameter.First;
while (item != null)
{
if (item.Value.kind == TypeKind.OpaqueType)
item.Value = ((OpaqueType)item.Value).resolvedType;
item = item.Next;
}
break;
case TypeKind.ListType:
ListType alist = (ListType)ulyssesType;
if (alist.innerType.kind == TypeKind.OpaqueType)
alist.SetInnerType(((OpaqueType)alist.innerType).resolvedType);
break;
case TypeKind.MapType:
MapType aMap = (MapType)ulyssesType;
if (aMap.fromType.kind == TypeKind.OpaqueType)
aMap.SetFromType(((OpaqueType)aMap.fromType).resolvedType);
if (aMap.toType.kind == TypeKind.OpaqueType)
aMap.SetToType(((OpaqueType)aMap.toType).resolvedType);
break;
/*case TypeKind.OoActionSystemType:
// handeled by the other cases...
break;*/
case TypeKind.TupleType:
TupleType aTuple = (TupleType)ulyssesType;
LinkedListNode titem = aTuple.innerTypes.First;
while (titem != null)
{
if (titem.Value.kind == TypeKind.OpaqueType)
titem.Value = ((OpaqueType)titem.Value).resolvedType;
titem = titem.Next;
}
break;
default:
throw new NotImplementedException();
}
}
protected override void VisitAstElement(IAst subElement, IAst parent)
{
base.VisitAstElement(subElement, parent);
/*see whether the subElement is an OpaqueType, we need
to replace.*/
if ((subElement != null)
&& (subElement.nodeType == AstNodeTypeEnum.type)
&& (((UlyssesType)subElement).kind == TypeKind.OpaqueType))
ReplaceOpaque(parent);
}
public OoaReplaceOpaqueVisitor(ParserState aState)
: base(aState)
{ }
}
}