/*******************************************************************************
 * Copyright (c) 2004, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
/*


 */
package org.eclipse.jem.workbench.utility;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;

import org.eclipse.jdt.core.dom.*;

import org.eclipse.jem.internal.instantiation.*;
 
/**
 * Create a parse tree from an AST node.
 * @since 1.0.0
 */
public class ParseTreeCreationFromAST extends ASTVisitor {
	protected final Resolver resolver;
	protected PTExpression expression;	// Each visit (or endvisit) will put into expression the result of the visit if it produced an expression.
	
	/**
	 * This is the abstract base class used by ParseTreeCreationFromAST to resolve the types to the appropriate
	 * types (e.g. "String" to "java.lang.String"). 
	 * 
	 * @see org.eclipse.jem.workbench.utility.ParseTreeCreationFromAST
	 * @since 1.0.0
	 */
	public static abstract class Resolver {
		
		/**
		 * Resolve the Name. It can return either a PTName if it is just a classname,
		 * or a PTFieldAccess if it resolves to a PTFieldAccess. The PTFieldAccess should
		 * be complete. e.g we have class like:
		 * <code>
		 * 	package xyz; 
		 * 	public class AClass {
		 * 		public java.awt.Rectangle rect;
		 * 	} 
		 * </code>
		 * Then a Name like <code>AClass.rect.x</code> should resolve to:
		 * 
		 * PTFieldAccess:
		 * 	receiver: 
		 * 		PTFieldAccess
		 * 			receiver: xyz.AClass
		 * 			field: "rect"
		 * 	field: "x"
		 *
		 * Actually it can return any valid expression that has a value (i.e. it cannot be a method invocation with a <code>void</code> return type). 
		 * 
		 * @param name
		 * @return Either a fully-qualified name (as a PTName) or a PTFieldAccess, any other type of expression.
		 * 
		 * @since 1.0.0
		 */
		public abstract PTExpression resolveName(Name name) throws InvalidExpressionException;
		
		/**
		 * Resolve the type. If it is an array type return it in format "type[][]".
		 * 
		 * @param type
		 * @return The type name, including brackets if array type.
		 * 
		 * @since 1.0.0
		 */
		public abstract String resolveType(Type type) throws InvalidExpressionException;
		
		/**
		 * This is for resolving "this" literal. It should either return a PTThisLiteral, if it
		 * can't do resolve, or some PTExpression that can resolve to "this" for evaluation.
		 * 
		 * @return If resolvable, a PTExpression, else a PTThisLiteral if not resolvable.
		 * @throws InvalidExpressionException
		 * 
		 * @since 1.0.0
		 */
		public abstract PTExpression resolveThis() throws InvalidExpressionException;
		
		/**
		 * Resolve the type specified as a Name. It may be a simple name or it may be
		 * a qualified name. This is used when we have Name that we know must be a
		 * type. This is so that there is no confusion with it possibly being a field or variable
		 * that has the same case and spelling as a type name.
		 * @param name
		 * @return the type name.
		 * @throws InvalidExpressionException
		 * 
		 * @since 1.0.0
		 */
		public abstract String resolveType(Name name) throws InvalidExpressionException;
		
		/**
		 * This is used by the resolver if it can't resolve for some reason. This will throw
		 * an invalid expression exception which will be handled by the ParseTreeCreationFromAST.
		 * 
		 * @param msg Message to be put into the exception.
		 * @throws InvalidExpressionException
		 * 
		 * @since 1.0.0
		 */
		protected final void throwInvalidExpressionException(String msg) throws InvalidExpressionException {
			throw new InvalidExpressionException(msg);
		}
	}
	
	/*
	 * When an invalid expression has been found this exception should be thrown. It will
	 * be caught at the top and converted into an InvalidExpression and the rest of the parse tree will be
	 * thrown away. 
	 * 
	 * The message will be a message as to why it is invalid.
	 * 
	 * @since 1.0.0
	 */
	protected static class InvalidExpressionException extends IllegalArgumentException {
		
		/**
		 * Comment for <code>serialVersionUID</code>
		 * 
		 * @since 1.1.0
		 */
		private static final long serialVersionUID = 2429845631915206678L;

		/**
		 * @param s The message to be used in the final invalid expression.
		 * 
		 * @since 1.0.0
		 */
		public InvalidExpressionException(String s) {
			super(s);
		}
	}

	/**
	 * Construct with the given resolver.
	 * 
	 * @param resolver
	 * 
	 * @since 1.0.0
	 */
	public ParseTreeCreationFromAST(Resolver resolver) {
		this.resolver = resolver;
	}

	/**
	 * Process the AST Expression and return a PTExpression. If any part was invalid, then
	 * only an PTInvalidExpression will be returned.
	 * 
	 * @param astExpression
	 * @return The PTExpression.
	 * 
	 * @since 1.0.0
	 */
	public final PTExpression createExpression(Expression astExpression) {
		try {
			return perform(astExpression);
		} catch (InvalidExpressionException e) {
			// Create a msg that is formed of the exception message and the full init string.
			String msg = MessageFormat.format(WorkbenchUtilityMessages.ParseTreeCreationFromAST_0, new Object[] {e.getLocalizedMessage(), astExpression.toString()}); 
			PTInvalidExpression exp = InstantiationFactory.eINSTANCE.createPTInvalidExpression();
			exp.setMessage(msg);
			return exp;
		}	
	}
	
	/*
	 * Visit the AST expression and get the ParseTree Expression.
	 * This is used by the individual visits when parsing a tree.
	 * It passes to the top method (createExpression), which can
	 * handle the InvalidExpressionException.
	 * 
	 * If any visit doesn't return an expression, then an invalid
	 * expression exception will be thrown to indicate this. If the
	 * incoming expression is <code>null</code>, then return of <code>null</code> is ok because
	 * this would be for an optional expression which didn't exist.
	 * 
	 * @return The new ParseTree Expression or <code>null</code> if incoming expression was null. 
	 * 
	 * @see createExpression(org.eclipse.jdt.core.dom.Expression)
	 * @exception InvalidExpressionException
	 * @since 1.0.0
	 */
	protected final PTExpression perform(Expression astExpression) {
		if (astExpression != null) {
			expression = null;
			astExpression.accept(this);
			if (expression == null)
				throw new InvalidExpressionException(MessageFormat.format(WorkbenchUtilityMessages.ParseTreeCreationFromAST_ExpressionTooComplicated_EXC_, new Object[] {astExpression.toString()})); 
			return expression;
		} else
			return null;	// This is ok. It means an optional expression was being processed and the expression didn't exist.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayAccess)
	 */
	public boolean visit(ArrayAccess node) {
		PTArrayAccess aa = InstantiationFactory.eINSTANCE.createPTArrayAccess();
		List indexes = aa.getIndexes();
		Expression arrayExp = node;
		while (arrayExp.getNodeType() == ASTNode.ARRAY_ACCESS) {
			// Visit the index to get the index expression.
			ArrayAccess array = (ArrayAccess) arrayExp; 
			indexes.add(0, perform(array.getIndex()));	// We're trying to create the final expression from inside out, the indexes are created in reverse order.
			arrayExp = array.getArray();
		}
		aa.setArray(perform(arrayExp));	// Final arrayExp is the true expression.
		expression = aa;	// Set the return expression for this visit.
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayCreation)
	 */
	public boolean visit(ArrayCreation node) {
		PTArrayCreation ac = InstantiationFactory.eINSTANCE.createPTArrayCreation();
		ac.setType(resolver.resolveType(node.getType()));
		List acDims = ac.getDimensions();
		List nDims = node.dimensions();
		int nsize = nDims.size();
		for (int i = 0; i < nsize; i++) {
			acDims.add(perform((Expression) nDims.get(i)));
		}
		ac.setInitializer((PTArrayInitializer) perform(node.getInitializer()));
		expression = ac;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ArrayInitializer)
	 */
	public boolean visit(ArrayInitializer node) {
		PTArrayInitializer ai = InstantiationFactory.eINSTANCE.createPTArrayInitializer();
		List exps = node.expressions();
		List aiexps = ai.getExpressions();
		int nexp = exps.size();
		for (int i = 0; i < nexp; i++) {
			aiexps.add(perform((Expression) exps.get(i)));
		}
		expression = ai;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Assignment)
	 */
	public boolean visit(Assignment node) {
		return false;	// We can't handle assignment.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.BooleanLiteral)
	 */
	public boolean visit(BooleanLiteral node) {
		PTBooleanLiteral bl = InstantiationFactory.eINSTANCE.createPTBooleanLiteral();
		bl.setBooleanValue(node.booleanValue());
		expression = bl;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CastExpression)
	 */
	public boolean visit(CastExpression node) {
		PTCastExpression ct	= InstantiationFactory.eINSTANCE.createPTCastExpression();
		ct.setType(resolver.resolveType(node.getType()));
		ct.setExpression(perform(node.getExpression()));
		expression = ct;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.CharacterLiteral)
	 */
	public boolean visit(CharacterLiteral node) {
		PTCharacterLiteral cl = InstantiationFactory.eINSTANCE.createPTCharacterLiteral();
		cl.setEscapedValue(node.getEscapedValue());
		cl.setCharValue(node.charValue());
		expression = cl;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ClassInstanceCreation)
	 */
	public boolean visit(ClassInstanceCreation node) {
		if (node.getAnonymousClassDeclaration() != null) { 
			PTAnonymousClassDeclaration adecl = InstantiationFactory.eINSTANCE.createPTAnonymousClassDeclaration();
			adecl.setDeclaration(node.toString());
			expression = adecl;
		} else {
			PTClassInstanceCreation cic = InstantiationFactory.eINSTANCE.createPTClassInstanceCreation();
			// If ast level = 2, then you must use getName, but the name needs to be turned into a type
			// so that it can be resolved. If ast level > 2, then it will return a type to be resolved.
			// Note: can't just use resolve name on the name because if a field and a class were spelled
			// the same then the codegen resolver would return an instance ref to the field instead.
			String type = node.getAST().apiLevel() == AST.JLS2 ? resolver.resolveType(node.getName()) : resolver.resolveType(node.getType());
			if (type == null) {
				type = node.getAST().apiLevel() == AST.JLS2 ? node.getName().getFullyQualifiedName() : node.getType().toString();
			}
			cic.setType(type);
			List args = cic.getArguments();
			List nargs = node.arguments();
			int nsize = nargs.size();
			for (int i = 0; i < nsize; i++) {
				args.add(perform((Expression) nargs.get(i)));
			}
			expression = cic;
		}
		return false;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ConditionalExpression)
	 */
	public boolean visit(ConditionalExpression node) {
		PTConditionalExpression ce = InstantiationFactory.eINSTANCE.createPTConditionalExpression();
		ce.setCondition(perform(node.getExpression()));
		ce.setTrue(perform(node.getThenExpression()));
		ce.setFalse(perform(node.getElseExpression()));
		expression = ce;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldAccess)
	 */
	public boolean visit(FieldAccess node) {
		expression = createFieldAccess(node.getName().getIdentifier(), perform(node.getExpression()));
		return false;
	}
	
	protected PTExpression createFieldAccess(String name, PTExpression receiver) {
		PTFieldAccess fa = InstantiationFactory.eINSTANCE.createPTFieldAccess();
		fa.setReceiver(receiver);
		fa.setField(name);
		return fa;
	}

	private static HashMap infixOperToParseOper;
	private final PTInfixOperator getParseInfix(InfixExpression.Operator operator) {
		if (prefixOperToParseOper == null) {
			infixOperToParseOper = new HashMap(5);
			infixOperToParseOper.put(InfixExpression.Operator.AND, PTInfixOperator.AND_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.CONDITIONAL_AND, PTInfixOperator.CONDITIONAL_AND_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.CONDITIONAL_OR, PTInfixOperator.CONDITIONAL_OR_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.DIVIDE, PTInfixOperator.DIVIDE_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.EQUALS, PTInfixOperator.EQUALS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.GREATER_EQUALS, PTInfixOperator.GREATER_EQUALS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.GREATER, PTInfixOperator.GREATER_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.LEFT_SHIFT, PTInfixOperator.LEFT_SHIFT_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.LESS_EQUALS, PTInfixOperator.LESS_EQUALS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.LESS, PTInfixOperator.LESS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.MINUS, PTInfixOperator.MINUS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.NOT_EQUALS, PTInfixOperator.NOT_EQUALS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.OR, PTInfixOperator.OR_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.PLUS, PTInfixOperator.PLUS_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.REMAINDER, PTInfixOperator.REMAINDER_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.RIGHT_SHIFT_SIGNED, PTInfixOperator.RIGHT_SHIFT_SIGNED_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED, PTInfixOperator.RIGHT_SHIFT_UNSIGNED_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.TIMES, PTInfixOperator.TIMES_LITERAL);
			infixOperToParseOper.put(InfixExpression.Operator.XOR, PTInfixOperator.XOR_LITERAL);
		}
		return (PTInfixOperator) infixOperToParseOper.get(operator);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InfixExpression)
	 */
	public boolean visit(InfixExpression node) {
		PTInfixExpression inf = InstantiationFactory.eINSTANCE.createPTInfixExpression();
		inf.setLeftOperand(perform(node.getLeftOperand()));
		PTInfixOperator inoper = getParseInfix(node.getOperator());
		if (inoper == null) {
			// It is not one we can handle.
			throw new InvalidExpressionException(
					MessageFormat.format(WorkbenchUtilityMessages.ParseTreeCreationFromAST_OperatorTooComplicatedToHandle_EXC_, new Object[] { node.getOperator().toString() })); 
		}
		inf.setOperator(inoper);
		inf.setRightOperand(perform(node.getRightOperand()));
		List eops = inf.getExtendedOperands();
		List neops = node.extendedOperands();
		int nsize = neops.size();
		for (int i = 0; i < nsize; i++) {
			eops.add(perform((Expression) neops.get(i)));
		}
		expression = inf;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InstanceofExpression)
	 */
	public boolean visit(InstanceofExpression node) {
		PTInstanceof inof = InstantiationFactory.eINSTANCE.createPTInstanceof();
		inof.setOperand(perform(node.getLeftOperand()));
		inof.setType(resolver.resolveType(node.getRightOperand()));
		expression = inof;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PostfixExpression)
	 */
	public boolean visit(PostfixExpression node) {
		return false;	// We can't handle post fix.
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodInvocation)
	 */
	public boolean visit(MethodInvocation node) {
		expression = createMethodInvocation(node.getName().getIdentifier(), perform(node.getExpression()), node.arguments());
		return false;
	}

	/**
	 * Create a method invocation using the giving receiver, name, args.
	 * @param node
	 * @return
	 * 
	 * @since 1.2.0
	 */
	protected PTMethodInvocation createMethodInvocation(String name, PTExpression receiver, List argExpressions) {
		PTMethodInvocation mi = InstantiationFactory.eINSTANCE.createPTMethodInvocation();
		mi.setReceiver(receiver);
		mi.setName(name);
		List args = mi.getArguments();
		int nsize = argExpressions.size();
		for (int i = 0; i < nsize; i++) {
			args.add(perform((Expression) argExpressions.get(i)));
		}
		return mi;
	}
	
	

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NullLiteral)
	 */
	public boolean visit(NullLiteral node) {
		expression = InstantiationFactory.eINSTANCE.createPTNullLiteral();
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.NumberLiteral)
	 */
	public boolean visit(NumberLiteral node) {
		PTNumberLiteral nl = InstantiationFactory.eINSTANCE.createPTNumberLiteral();
		nl.setToken(node.getToken());
		expression = nl;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ParenthesizedExpression)
	 */
	public boolean visit(ParenthesizedExpression node) {
		PTParenthesizedExpression pe = InstantiationFactory.eINSTANCE.createPTParenthesizedExpression();
		pe.setExpression(perform(node.getExpression()));
		expression = pe;
		return false;
	}

	private static HashMap prefixOperToParseOper;
	private final PTPrefixOperator getParsePrefix(PrefixExpression.Operator operator) {
		if (prefixOperToParseOper == null) {
			prefixOperToParseOper = new HashMap(5);
			prefixOperToParseOper.put(PrefixExpression.Operator.COMPLEMENT, PTPrefixOperator.COMPLEMENT_LITERAL);
			prefixOperToParseOper.put(PrefixExpression.Operator.MINUS, PTPrefixOperator.MINUS_LITERAL);
			prefixOperToParseOper.put(PrefixExpression.Operator.NOT, PTPrefixOperator.NOT_LITERAL);
			prefixOperToParseOper.put(PrefixExpression.Operator.PLUS, PTPrefixOperator.PLUS_LITERAL);
		}
		return (PTPrefixOperator) prefixOperToParseOper.get(operator);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PrefixExpression)
	 */
	public boolean visit(PrefixExpression node) {
		if (node.getOperand().getNodeType() == ASTNode.NUMBER_LITERAL) {
			// For number literals we see if it is a "+" or "-" prefix, and if it is, we simply
			// create a PTNumberLiteral with the operator already in it. It is a simplification.
			// Any other operator we've left alone since those won't be decoded simply by the
			// Number decoder.
			// If not a number literal, then leave alone since needs to be handled as a prefix
			// operation.
			PrefixExpression.Operator operator = node.getOperator();
			if (operator == PrefixExpression.Operator.PLUS || operator == PrefixExpression.Operator.MINUS) {
				PTNumberLiteral nm = InstantiationFactory.eINSTANCE.createPTNumberLiteral();
				nm.setToken(operator.toString() + ((NumberLiteral) node.getOperand()).getToken());
				expression = nm;
				return false;
			}
		}

		PTPrefixExpression pe = InstantiationFactory.eINSTANCE.createPTPrefixExpression();
		PTPrefixOperator ptoper = getParsePrefix(node.getOperator());
		if (ptoper == null) {
			// It is not one we can handle.
			throw new InvalidExpressionException(
				MessageFormat.format(WorkbenchUtilityMessages.ParseTreeCreationFromAST_OperatorTooComplicatedToHandle_EXC_, new Object[] { node.getOperator().toString() })); 
		}
		pe.setOperator(ptoper);
		pe.setExpression(perform(node.getOperand()));
		expression = pe;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedName)
	 */
	public boolean visit(QualifiedName node) {
		expression = resolver.resolveName(node);
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleName)
	 */
	public boolean visit(SimpleName node) {
		expression = resolver.resolveName(node);
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.StringLiteral)
	 */
	public boolean visit(StringLiteral node) {
		PTStringLiteral sl = InstantiationFactory.eINSTANCE.createPTStringLiteral();
		sl.setEscapedValue(node.getEscapedValue());
		sl.setLiteralValue(node.getLiteralValue());
		expression = sl;
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperFieldAccess)
	 */
	public boolean visit(SuperFieldAccess node) {
		expression = createFieldAccess(node.getName().getIdentifier(), resolver.resolveThis());
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SuperMethodInvocation)
	 */
	public boolean visit(SuperMethodInvocation node) {
		expression = createMethodInvocation(node.getName().getIdentifier(), resolver.resolveThis(), node.arguments());
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.ThisExpression)
	 */
	public boolean visit(ThisExpression node) {
		expression = resolver.resolveThis();
		return false;	
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeLiteral)
	 */
	public boolean visit(TypeLiteral node) {
		PTTypeLiteral ptl = InstantiationFactory.eINSTANCE.createPTTypeLiteral();
		ptl.setType(resolver.resolveType(node.getType()));
		expression = ptl;
		return false;
	}

}
