| /* |
| * Copyright 2003-2007 the original author or authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.codehaus.groovy.antlr.java; |
| |
| import java.util.Stack; |
| |
| import org.codehaus.groovy.antlr.GroovySourceAST; |
| import org.codehaus.groovy.antlr.treewalker.VisitorAdapter; |
| |
| /** This class mutates the Java AST, whilst it is still a Java AST, in readiness for conversion to Groovy, yippee-ky-a ! */ |
| public class PreJava2GroovyConverter extends VisitorAdapter{ |
| private String[] tokenNames; |
| private Stack stack; |
| |
| public PreJava2GroovyConverter(String[] tokenNames) { |
| this.tokenNames = tokenNames; |
| this.stack = new Stack(); |
| } |
| |
| public void visitDefault(GroovySourceAST t,int visit) { |
| if (visit == OPENING_VISIT) { |
| if (t.getType() == JavaTokenTypes.LITERAL_do) { |
| visitJavaLiteralDo(t); |
| } else if (t.getType() == JavaTokenTypes.ARRAY_INIT) { |
| visitJavaArrayInit(t); |
| } |
| } |
| } |
| |
| private void visitJavaLiteralDo(GroovySourceAST t) { |
| // todo - incomplete, as body of do...while... should be executed at least once, which this doesn't provide. |
| swapTwoChildren(t); |
| } |
| /** |
| * <pre> |
| * String[] myArray = new String[] {"a","b","c"}; |
| * |
| * becomes |
| * |
| * String[] myArray = ["a", "b", "c"] |
| * |
| * --- |
| * |
| * To convert node (t) and surrounding nodes into the right structure for List Constructor |
| * |
| * (a) java/EXPR |
| * | |
| * +- (b) java/new |
| * | |
| * + (t) java/ARRAY_INIT |
| * |
| * becomes |
| * |
| * (a) groovy/LIST_CONSTRUCTOR (via ARRAY_INIT as temporary marker type) |
| * | |
| * +- (t) groovy/ELIST |
| * |
| * * note: node (b) is thrown away... |
| * </pre> |
| */ |
| private void visitJavaArrayInit(GroovySourceAST t) { |
| // given that we might have a grandParent... |
| if (stack.size() > 2) { |
| GroovySourceAST grandParent = getGrandParentNode(); |
| if (grandParent.getType() == JavaTokenTypes.EXPR) { |
| grandParent.setType(JavaTokenTypes.ARRAY_INIT); //set type as indicator for Java2GroovyConvertor to turn into LIST_CONSTRUCTOR |
| grandParent.setFirstChild(t); |
| t.setType(JavaTokenTypes.ELIST); |
| } |
| } |
| } |
| |
| /** To swap two children of node t... |
| * |
| *<pre> |
| * (t) |
| * | |
| * | |
| * (a) -- (b) |
| * |
| * t.down = firstNode |
| * a.right = b |
| * b.right = null |
| *</pre> |
| * becomes |
| *<pre> |
| * (t) |
| * | |
| * | |
| * (b) -- (a) |
| * |
| * t.down = b |
| * a.right = null |
| * b.right = a |
| *</pre> |
| * |
| * todo - build API of basic tree mutations like this method. |
| */ |
| public void swapTwoChildren(GroovySourceAST t) { |
| // this swaps the two child nodes, see javadoc above for explanation of implementation |
| GroovySourceAST a = (GroovySourceAST) t.getFirstChild(); |
| GroovySourceAST b = (GroovySourceAST) a.getNextSibling(); |
| |
| t.setFirstChild(b); |
| a.setNextSibling(null); |
| b.setNextSibling(a); |
| } |
| |
| |
| |
| |
| public void push(GroovySourceAST t) { |
| stack.push(t); |
| } |
| public GroovySourceAST pop() { |
| if (!stack.empty()) { |
| return (GroovySourceAST) stack.pop(); |
| } |
| return null; |
| } |
| |
| private GroovySourceAST getParentNode() { |
| Object currentNode = stack.pop(); |
| Object parentNode = stack.peek(); |
| stack.push(currentNode); |
| return (GroovySourceAST) parentNode; |
| } |
| |
| private GroovySourceAST getGrandParentNode() { |
| Object currentNode = stack.pop(); |
| Object parentNode = stack.pop(); |
| Object grandParentNode = stack.peek(); |
| stack.push(parentNode); |
| stack.push(currentNode); |
| return (GroovySourceAST) grandParentNode; |
| } |
| } |