blob: bbb8177b0153464938fe16b299cdcb201274047a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 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.wst.jsdt.web.ui.tests.translation;
import java.util.List;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.wst.jsdt.core.IBuffer;
import org.eclipse.wst.jsdt.core.IFunction;
import org.eclipse.wst.jsdt.core.IJavaScriptElement;
import org.eclipse.wst.jsdt.core.IJavaScriptUnit;
import org.eclipse.wst.jsdt.core.IType;
import org.eclipse.wst.jsdt.core.JavaScriptCore;
import org.eclipse.wst.jsdt.core.JavaScriptModelException;
import org.eclipse.wst.jsdt.core.dom.AST;
import org.eclipse.wst.jsdt.core.dom.ASTNode;
import org.eclipse.wst.jsdt.core.dom.ASTParser;
import org.eclipse.wst.jsdt.core.dom.ASTVisitor;
import org.eclipse.wst.jsdt.core.dom.Assignment;
import org.eclipse.wst.jsdt.core.dom.Block;
import org.eclipse.wst.jsdt.core.dom.ExpressionStatement;
import org.eclipse.wst.jsdt.core.dom.FunctionInvocation;
import org.eclipse.wst.jsdt.core.dom.JavaScriptUnit;
import org.eclipse.wst.jsdt.core.dom.ObjectLiteral;
import org.eclipse.wst.jsdt.core.dom.ObjectLiteralField;
import org.eclipse.wst.jsdt.core.dom.QualifiedName;
import org.eclipse.wst.jsdt.core.dom.StringLiteral;
import org.eclipse.wst.jsdt.internal.core.DocumentAdapter;
import org.eclipse.wst.jsdt.internal.corext.ValidateEditException;
import org.eclipse.wst.jsdt.internal.corext.util.JavaModelUtil;
import org.eclipse.wst.jsdt.internal.ui.javaeditor.JavaEditor;
/**
* Connected handler for whatever we need it to be
*
* Invoke with M1+M2+7
*
* @author nitin
*/
public class RunCodeHandler extends AbstractHandler {
/**
*
*/
public RunCodeHandler() {
}
static final class MyNodeVisitor extends ASTVisitor{
IJavaScriptUnit jsUnit;
String className;
private JavaScriptUnit cu;
public MyNodeVisitor(IJavaScriptUnit jsUnit, String className, ASTNode ast) {
super();
this.jsUnit = jsUnit;
this.className = className;
this.cu = (JavaScriptUnit) ast;
}
public boolean visit(org.eclipse.wst.jsdt.core.dom.FunctionDeclaration node) {
// this.jsUnit = (IJavaScriptUnit) node.getRoot();
Block body = node.getBody();
try {
IJavaScriptElement element = jsUnit.getElementAt(body.getStartPosition());
if (element instanceof IFunction) {
IFunction function = (IFunction) element;
if (!function.isConstructor() && function.getDisplayName().equals("sayHello")) {
IType type = function.getDeclaringType();
if (type != null /*&& type.getDisplayName().equals(className)*/) {
cu.recordModifications();
AST ast = node.getAST();
// String newField = "dojo.declare(\"temp\", null,{handler : function(){ }});";
String functionLiteral = "handler : function(args){alert(\"Hello\");}";
ObjectLiteralField field = getObjectLiteralField(functionLiteral);
//creating the function
// AST parentAST = node.getParent().getAST();
// FunctionDeclaration decl = parentAST.newFunctionDeclaration();
// decl.setName(parentAST.newSimpleName("handler"));
// Block block = parentAST.newBlock();
//// block.statements().add(parentAST.newExpressionStatement(parentAST.newBlockComment()));
// decl.setBody(block);
List fields = ((ObjectLiteral)(node.getParent().getParent().getParent())).fields();
fields.add(field);
// node.getParent().getBody().statements().add(decl);
// SourceType sty ;
// sty.createMethod(contents, sibling, force, monitor)
// ExpressionStatement st = parentAST.newExpressionStatement(decl);
FunctionInvocation methodInvocation = ast.newFunctionInvocation();
QualifiedName name = ast.newQualifiedName(ast.newSimpleName("dojo"),ast.newSimpleName("connect"));//$NON-NLS-1$
methodInvocation.setExpression(name);
methodInvocation.arguments().add(ast.newSimpleName("a"));
StringLiteral lit = ast.newStringLiteral();
lit.setLiteralValue("a");
methodInvocation.arguments().add(lit);
ExpressionStatement expressionStatement = ast.newExpressionStatement(methodInvocation);
body.statements().add(expressionStatement);
TextEdit edits= cu.rewrite(getDocument(jsUnit), JavaScriptCore.getDefaultOptions());
try {
JavaModelUtil.applyEdit(jsUnit, edits, true, new NullProgressMonitor());
} catch (ValidateEditException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// jsUnit.becomeWorkingCopy(null);
// get source and make changes to the body directly in the buffer
// String source = jsUnit.getBuffer().getText(body.getStartPosition(), body.getLength());
// String toInsert = "\tdojo.connect(a ,b , c, d);\n";
// int offset = body.getStartPosition()+ body.getLength()-1;
// IBuffer buffer = jsUnit.getBuffer();
// buffer.replace(offset, 0, toInsert);
// OR build the syntax up using AST manipulation
//
// ImportDeclaration id = nodeAst.newImportDeclaration();
// id.setName(nodeAst.newName(new String[] {"java", "util", "Set"}));
//
// FunctionInvocation replacement= nodeAst.newFunctionInvocation();
//
//
//
// ASTRewrite rewriter = ASTRewrite.create(nodeAst);
//
// replacement.setName((SimpleName) rewriter.createCopyTarget(function.getName()));
// replacement.arguments().add(nodeAst.newThisExpression());
// replacement.setExpression((Expression) rewriter.createCopyTarget(right));
// rewriter.replace(method, replacement, null);
//
//
// TypeDeclaration td = (TypeDeclaration) cu.types().get(0);
// ITrackedNodePosition tdLocation = rewriter.track(td);
// ListRewrite lrw = rewriter.getListRewrite(cu, JavaScriptUnit.TYPES_PROPERTY);
// lrw.insertLast(id, null);
// IDocument doc = getDocument(jsUnit);
// TextEdit edits = rewriter.rewriteAST(doc, null);
// try {
// UndoEdit undo = edits.apply(doc);
// } catch (MalformedTreeException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// } catch (BadLocationException e1) {
// // TODO Auto-generated catch block
// e1.printStackTrace();
// }
//
// jsUnit.commitWorkingCopy(true, new NullProgressMonitor());
// jsUnit.discardWorkingCopy();
}
}
}
}
catch (JavaScriptModelException e) {
e.printStackTrace();
}
return false;
};
}
protected void doExecute(IFile jsFile) {
IProject project = jsFile.getProject();
// String namespace = CodeGenUtil.getNameSpace(project);
// final String className = IPCCommandUtil.getPortletHelperClassName(jsFile, namespace);
final IJavaScriptUnit jsUnit = (IJavaScriptUnit) JavaScriptCore.create(jsFile);
if (jsUnit == null)
return;
IProgressMonitor monitor = null;
if (monitor == null) {
monitor = new NullProgressMonitor();
}
////////////////////////////////////////////////////////////////////////////////
// this part may not be of interest for what you're trying to do
// IType t = null;
// try{
// for (org.eclipse.wst.jsdt.core.IFunction function : jsUnit.getFunctions()) {
// // functions declared in the file outside of any types
// org.eclipse.wst.jsdt.core.ISourceRange sourceRange = function.getSourceRange();
// String source = jsUnit.getBuffer().getText(sourceRange.getOffset(), sourceRange.getLength());
// }
//
// // start with the types in the file
// IType[] types = jsUnit.getTypes();
//
// for (IType type: types) {
//// if (type.getDisplayName().equals(className)) {
// t = type;
// for (IFunction function : type.getFunctions()) {
// // functions declared in a type
// if(function.getDisplayName().equals("sayHello") && !function.isConstructor()) {
// ISourceRange sourceRange = function.getSourceRange();
// String source = jsUnit.getBuffer().getText(sourceRange.getOffset(), sourceRange.getLength());
// }
// }
//// }
// }
// }catch (JavaScriptModelException e) {
// // TODO: handle exception
// //;
// }
//It would be more accurate to walk the AST of the file instead of searching just the top-level children:
// SourceType st = null;
// if(t instanceof SourceType)
// st = (SourceType) t;
// try {
// if(st!=null)
// st.createMethod("function hello(args){}", null, false, null);
//
// } catch (JavaScriptModelException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
ASTParser parser = org.eclipse.wst.jsdt.core.dom.ASTParser.newParser(AST.JLS3);
parser.setSource(jsUnit);
ASTNode ast = parser.createAST(null);
ASTVisitor visitor = new MyNodeVisitor(jsUnit,/*className*/null , ast);
ast.accept(visitor);
}
////////////////////////////////////////////////////////////////////////////////
//
// try {
// // TODO: check for dirty state first, and save all the opened documents
// //then do the operation
//
// jsUnit.becomeWorkingCopy(monitor);
// IJavaScriptElement[] children = jsUnit.getChildren();
// for (IJavaScriptElement javaScriptElement : children) {
// if(javaScriptElement instanceof SourceType){
// SourceType st = (SourceType) javaScriptElement;
// if(st.isClass()){
// if(st.getDisplayName().equals(className)){
// SourceTypeElementInfo info = (SourceTypeElementInfo) st.getElementInfo();
// IJavaScriptElement[] infoChildren =info.getChildren();
// boolean found = false;
// SourceMethod method = null;
// for (IJavaScriptElement javaScriptElement2 : infoChildren) {
// if(javaScriptElement2 instanceof SourceMethod){
// method = (SourceMethod) javaScriptElement2;
// if(method.getDisplayName().equals("sayHello")){
// found = true;
// break;
// }
// }
// }
// if(found){
//
// IPath filePath = jsFile.getFullPath();
// String toInsert = "dojo.connect(a ,b , c, d)";
// int offset = method.getSourceRange().getOffset();
// IBuffer source = jsUnit.getBuffer();
//// source.replace(offset+1, 0, toInsert);
//// st.createMethod("hello: function(){ var x=5 }", null, true, monitor);
// //method.
// IDocument document = getDocument(jsUnit);
// CompilationUnitChange result = new CompilationUnitChange("Insert dojo connect", jsUnit);
// AST cu;
// if(jsUnit instanceof JavaScriptUnit){
// cu =((JavaScriptUnit)jsUnit).getAST();
// ASTRewrite rewriter = ASTRewrite.create(cu);
//
// }else {
// ASTParser parser = ASTParser.newParser(AST.JLS3);
// parser.setSource(document.get().toCharArray());
// JavaScriptUnit cu = (JavaScriptUnit) parser.createAST(null);
// cu = cu.getAST();
// cu.getBodyChild();
// List<Object> stmts = cu.statements();
// ExpressionStatement stmt = (ExpressionStatement) stmts.get(2);
//// stmt.get
// for (Object object : stmts) {
// object = object;
// ((ExpressionStatement)object).getAST();
// //ASTNodes.getBodyDeclarations((ExpressionStatement)object);
// FunctionInvocation fi = (FunctionInvocation) (ASTNodes.getChildren((ExpressionStatement)object)).get(0);
// fi.getBodyChild();
//// fi.
// }
//
// FunctionInvocation invocation = cu.newFunctionInvocation();
// }
//
//
//
// //testing only...
//// IJavaScriptElement[] elements = method.getChildren();
//// String source = method.getSource();
//// Object info1 = method.getElementInfo();
//// IJavaScriptModel model = method.getJavaScriptModel();
////// model = model;
//// st.createMethod("myfun : function(){}", method, true, monitor);
// }
//// info = info;
// }
//
// }
// }
// }
//// String toInsert = "dojo.connect(a ,b , c, d)";
//// int offset = 50;
//// IBuffer source = jsUnit.getBuffer();
//// source.replace(offset+1, 0, toInsert);
//// IBuffer source = jsUnit.getBuffer();
//// jsUnit.getBuffer().append("\n" + "var x;");
// jsUnit.commitWorkingCopy(true, monitor);
// jsUnit.discardWorkingCopy();
// } catch (JavaScriptModelException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
protected static IDocument getDocument(IJavaScriptUnit cu) throws JavaScriptModelException {
IBuffer buffer = cu.getBuffer();
if (buffer instanceof IDocument)
return (IDocument) buffer;
return new DocumentAdapter(buffer);
}
static ObjectLiteralField getObjectLiteralField(String source){
String js = "x.prototype = {" + source + "}";
JavaScriptUnit jsu = getAST(js);
ExpressionStatement stmt = (ExpressionStatement)jsu.statements().get(0);
ObjectLiteral lit = (ObjectLiteral)((Assignment) stmt.getExpression()).getRightHandSide();
ObjectLiteralField field = (ObjectLiteralField) lit.fields().get(0);
ASTNode node = ASTNode.copySubtree(jsu.getAST(), field);
return (ObjectLiteralField) node;
}
static JavaScriptUnit getAST(String source){
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setSource(source.toCharArray());
ASTNode ast = parser.createAST(null);
return (JavaScriptUnit) ast;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands
* .ExecutionEvent)
*/
public Object execute(final ExecutionEvent event) throws ExecutionException {
IEditorPart activeEditor = HandlerUtil.getActiveEditor(event);
if (!(activeEditor instanceof JavaEditor)) {
return null;
}
doExecute((IFile) HandlerUtil.getActiveEditor(event).getEditorInput().getAdapter(IFile.class));
return null;
}
}