blob: aea621c25322e4497905380fa35cc844475a7623 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2009-2010 Thales Corporate Services S.A.S.
* 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:
* Thales Corporate Services S.A.S - initial API and implementation
*
* </copyright>
*/
package org.eclipse.egf.emf.pattern.codegen.jet;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.egf.emf.pattern.codegen.jet.CodegenJetTemplateSection.InternalSection;
import org.eclipse.egf.emf.pattern.codegen.model.VariableInfo;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.ExpressionStatement;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Statement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
/**
* @author Matthieu Helleboid
*
*/
public class CodegenJetVariablesResolver {
protected CodegenJetCompiler codegenJetCompiler;
protected IProject codegenProject;
public CodegenJetVariablesResolver(CodegenJetCompiler codegenJetCompiler, IProject codegenProject) {
this.codegenJetCompiler = codegenJetCompiler;
this.codegenProject = codegenProject;
}
public void computeVariables() {
findAstNodes();
findVariables();
}
protected void findVariablesInScope(ASTNode node, final List<VariableInfo> variables) {
ASTNode parent = node.getParent();
while (parent != null) {
VariablesScopeVisitor visitor = createVariablesScopeVisitor(node, variables);
parent.accept(visitor);
parent = parent.getParent();
}
}
protected VariablesScopeVisitor createVariablesScopeVisitor(ASTNode node, final List<VariableInfo> variables) {
return new VariablesScopeVisitor(node, variables);
}
protected void findVariables() {
for (InternalSection section : codegenJetCompiler.allSections) {
findVariablesInScope(section.beginNode, section.getBeginVariables());
findVariablesInScope(section.endNode, section.getEndVariables());
}
}
protected void findAstNodes() {
ASTParser astParser = ASTParser.newParser(AST.JLS3);
astParser.setSource(codegenJetCompiler.javaBuffer.toString().toCharArray());
astParser.setResolveBindings(true);
astParser.setUnitName("MyClass"); //$NON-NLS-1$
IJavaProject javaProject = JavaCore.create(codegenProject);
astParser.setProject(javaProject);
astParser.setCompilerOptions(Collections.EMPTY_MAP);
ASTNode astNode = astParser.createAST(new NullProgressMonitor());
ASTVisitor visitor = new ASTVisitor() {
@Override
public boolean visit(ExpressionStatement node) {
if (CodegenJetConstants.MARK_STATEMENT.equals(node.toString())) {
for (InternalSection section : codegenJetCompiler.allSections) {
if (section.beginNode == null && section.beginJavaOffset == node.getStartPosition())
section.beginNode = node;
if (section.endNode == null && section.endJavaOffset == node.getStartPosition())
section.endNode = node;
}
}
return super.visit(node);
}
};
astNode.accept(visitor);
for (InternalSection section : codegenJetCompiler.allSections)
if (section.beginNode == null || section.endNode == null)
throw new IllegalStateException("Some ast nodes weren't found"); //$NON-NLS-1$
}
protected class VariablesScopeVisitor extends ASTVisitor {
private ASTNode finalNode;
private List<VariableInfo> variables;
public VariablesScopeVisitor(ASTNode finalNode, List<VariableInfo> variables) {
this.finalNode = finalNode;
this.variables = variables;
}
protected String getTypeString(Type type) {
ITypeBinding resolveBinding = type.resolveBinding();
if (resolveBinding == null)
throw new IllegalStateException("Unable to resolve bindings"); //$NON-NLS-1$
String typeString = resolveBinding.getBinaryName();
if ("Z".equals(typeString)) //$NON-NLS-1$
return "java.lang.Boolean"; //$NON-NLS-1$
if ("I".equals(typeString)) //$NON-NLS-1$
return "java.lang.Integer"; //$NON-NLS-1$
return typeString;
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(Block node) {
List<Statement> statements = node.statements();
for (Statement blockStatement : statements) {
if (blockStatement.getStartPosition() < finalNode.getStartPosition()) {
if (blockStatement instanceof VariableDeclarationStatement) {
VariableDeclarationStatement statement = (VariableDeclarationStatement) blockStatement;
if (statement.fragments().size() != 1)
throw new IllegalStateException("Not supported."); //$NON-NLS-1$
String type = getTypeString(statement.getType());
VariableDeclarationFragment fragment = (VariableDeclarationFragment) statement.fragments().get(0);
String name = fragment.getName().getIdentifier();
variables.add(new VariableInfo(type, name, null));
}
}
}
return false;
}
@Override
public boolean visit(EnhancedForStatement node) {
SingleVariableDeclaration parameter = node.getParameter();
String type = getTypeString(parameter.getType());
String name = parameter.getName().getIdentifier();
variables.add(new VariableInfo(type, name, null));
return false;
}
@Override
public boolean visit(IfStatement node) {
return false;
}
@Override
public boolean visit(MethodDeclaration node) {
return false;
}
@Override
public boolean visit(Initializer node) {
return false;
}
@Override
public boolean visit(TypeDeclaration node) {
return false;
}
@Override
public boolean visit(CompilationUnit node) {
return false;
}
}
}