blob: 76fb1531c29c32a8200ea7a6974257cf779a3964 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 itemis AG (http://www.itemis.eu) 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
*******************************************************************************/
package org.eclipse.xtext.example.arithmetics.ui.autoedit;
import java.math.BigDecimal;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentCommand;
import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument;
import org.eclipse.xtext.example.arithmetics.arithmetics.Evaluation;
import org.eclipse.xtext.example.arithmetics.arithmetics.Module;
import org.eclipse.xtext.example.arithmetics.arithmetics.Statement;
import org.eclipse.xtext.example.arithmetics.interpreter.Calculator;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
/**
* @author Sven Efftinge - initial contribution and API
*
* an interactive interpreter as an {@link IAutoEditStrategy}
*/
public class InterpreterAutoEdit implements IAutoEditStrategy {
public void customizeDocumentCommand(IDocument document,
DocumentCommand command) {
for (String lineDelimiter : document.getLegalLineDelimiters()) {
if (command.text.equals(lineDelimiter)) {
int line;
int lineStart;
try {
line = document.getLineOfOffset(command.offset);
lineStart = document.getLineOffset(line);
if (!document.get(lineStart, 3).equals("def")) {
BigDecimal computedResult = computeResult(document,
command);
if (computedResult != null)
command.text = lineDelimiter + "// = " + computedResult + lineDelimiter;
}
} catch (BadLocationException e) {
// ignore
}
}
}
}
private BigDecimal computeResult(IDocument document,
final DocumentCommand command) {
return ((IXtextDocument) document)
.readOnly(new IUnitOfWork<BigDecimal, XtextResource>() {
public BigDecimal exec(XtextResource state)
throws Exception {
Evaluation stmt = findEvaluation(command, state);
if (stmt == null)
return null;
return evaluate(stmt);
}
});
}
protected BigDecimal evaluate(Evaluation stmt) {
return new Calculator().evaluate(stmt.getExpression());
}
protected Evaluation findEvaluation(final DocumentCommand command,
XtextResource state) {
if(!state.getContents().isEmpty()) {
Module m = (Module) state.getContents().get(0);
for (Statement stmt : m.getStatements()) {
if (stmt instanceof Evaluation) {
ICompositeNode node = NodeModelUtils.getNode(stmt);
if (node.getOffset() <= command.offset
&& (node.getOffset() + node.getLength()) >= command.offset) {
return (Evaluation) stmt;
}
}
}
}
return null;
}
}