Commit 10e8154b authored by Sebastian Pretscher's avatar Sebastian Pretscher

Merge branch 'master' of git@github.com:jroith/cup-eclipse.git

parents 0987fa5c 72e40b78
......@@ -19,7 +19,6 @@ public class ConflictManager
}
public void addConflict(Conflict conflict) {
System.out.println("DEBUG: ADDING CONFLICT TO " + this + "!"); // TODO: remove
this.conflicts.add(conflict);
}
}
......
......@@ -16,6 +16,7 @@ public class CupContext
private ErrorManager errorManager;
private ConflictManager conflictManager;
private Statistics statistics;
private HashMap<String, Object> singletons = new HashMap<String, Object>();
public <T> T getForContext(Class<T> cls)
......@@ -85,8 +86,13 @@ public class CupContext
return conflictManager;
}
public Statistics getStatistics() {
return statistics;
}
public CupContext (IErrorReporter er) {
this.errorManager = new ErrorManager(er);
this.statistics = new Statistics();
this.errorManager = new ErrorManager(er, statistics);
this.conflictManager = new ConflictManager(this);
}
......
......@@ -16,13 +16,13 @@ public class CupScanner
public CupScanner(IErrorReporter er, InputStream is) {
ComplexSymbolFactory factory = new ComplexSymbolFactory();
ErrorManager errMan = new ErrorManager(er);
ErrorManager errMan = new ErrorManager(er, null);
this.lexer = new Lexer(errMan, factory, is);
}
public CupScanner(IErrorReporter er, Reader r) {
ComplexSymbolFactory factory = new ComplexSymbolFactory();
ErrorManager errMan = new ErrorManager(er);
ErrorManager errMan = new ErrorManager(er, null);
this.lexer = new Lexer(errMan, factory, r);
}
......
......@@ -6,6 +6,7 @@ import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;
public class ErrorManager
{
private Statistics statistics;
private IErrorReporter er;
private int error_count;
private int parser_error_count;
......@@ -36,8 +37,9 @@ public class ErrorManager
return error_count;
}
public ErrorManager (IErrorReporter er) {
public ErrorManager (IErrorReporter er, Statistics statistics) {
this.er = er;
this.statistics = statistics;
}
public void Warning(ErrorSource source, String msg, ComplexSymbol sym) {
......@@ -111,6 +113,8 @@ public class ErrorManager
public void Error(ErrorSource source, String msg, Position start, Position end) {
er.report(ErrorType.Error, source, null, msg, start, end);
error_count++;
if (statistics != null)
statistics.incrementErrorCount();
switch (source) {
case Parser: parser_error_count++; break;
case Scanner: scanner_error_count++; break;
......
package de.in.tum.www2.cup;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import de.in.tum.www2.cup.internal.*;
public class Statistics
{
private int error_count;
private int parser_error_count;
private int scanner_error_count;
private int lalr_error_count;
public int getErrorCount() {
return error_count;
}
public int getParserErrorCount() {
return parser_error_count;
}
public int getScannerErrorCount() {
return scanner_error_count;
}
public int getLalrErrorCount() {
return lalr_error_count;
}
void incrementErrorCount() {
error_count += 1;
}
}
......@@ -31,7 +31,7 @@ import de.tum.in.www2.cupplugin.model.Model;
public class DocumentDidChangeJob extends Job {
boolean iAmCurrentlyRunning = false;
CupTextEditor myEditor = null;
CupTextEditor editor = null;
private List<DocumentEvent> documentEvents;
private EnumSet<JobsToDo> jobs;
......@@ -47,7 +47,7 @@ public class DocumentDidChangeJob extends Job {
public DocumentDidChangeJob(CupTextEditor editor) {
super("" + editor.hashCode());
myEditor = editor;
this.editor = editor;
jobStatusList = new ArrayList<JobStatus>();
}
......@@ -87,20 +87,20 @@ public class DocumentDidChangeJob extends Job {
// We need these null checks, because the document might have been
// closed already.
if (myEditor == null)
if (editor == null)
return Status.CANCEL_STATUS;
IDocumentProvider provider = myEditor.getDocumentProvider();
IDocumentProvider provider = editor.getDocumentProvider();
if (provider == null)
return Status.CANCEL_STATUS;
IDocument document = provider.getDocument(myEditor.getEditorInput());
IDocument document = provider.getDocument(editor.getEditorInput());
if (document == null)
return Status.CANCEL_STATUS;
IFile file = ((FileEditorInput) myEditor.getEditorInput()).getFile();
IFile file = ((FileEditorInput) editor.getEditorInput()).getFile();
CupEditorErrorReporter errorReporter = new CupEditorErrorReporter(file);
errorReporter.resetOnNextPush();
......@@ -123,8 +123,8 @@ public class DocumentDidChangeJob extends Job {
if (result != null) {
jobStatusList.add(new JobStatus(JobsToDo.parseCode, false));
ParserResultJob resultModelJob = new ParserResultJob(result,
context, revNumber);
ParserResultJob resultModelJob = new ParserResultJob(editor,
result, context, revNumber);
resultModelJob.setSystem(true);
resultModelJob.schedule();
try {
......@@ -133,8 +133,12 @@ public class DocumentDidChangeJob extends Job {
e.printStackTrace();
}
} else {
StatisticsIfFailedJob statisticsJob = new StatisticsIfFailedJob(
editor, context, revNumber);
statisticsJob.setSystem(true);
statisticsJob.schedule();
// TODO: we need to notify listeners THAT/WHY the call failed.
jobStatusList.add(new JobStatus(JobsToDo.parseCode, true));
//return Status.CANCEL_STATUS;
}
......@@ -162,8 +166,8 @@ public class DocumentDidChangeJob extends Job {
if (lalrResult != null) {
jobStatusList.add(new JobStatus(JobsToDo.buildTable, false));
LaLrResultJob resultLaLrModelJob = new LaLrResultJob(myEditor,
lalrResult, revNumber, context);
LaLrResultJob resultLaLrModelJob = new LaLrResultJob(
editor, lalrResult, revNumber, context);
resultLaLrModelJob.setSystem(true);
resultLaLrModelJob.schedule();
try {
......@@ -173,9 +177,16 @@ public class DocumentDidChangeJob extends Job {
e.printStackTrace();
}
} else {
// TODO: we need to notify listeners THAT/WHY the call failed.
// TODO: we run the statistics job twice, here, even if we failed
// to build the parser. This should only run once.
StatisticsIfFailedJob statisticsJob = new StatisticsIfFailedJob(
editor, context, revNumber);
statisticsJob.setSystem(true);
statisticsJob.schedule();
jobStatusList.add(new JobStatus(JobsToDo.buildTable, true));
//return Status.CANCEL_STATUS;
}
}
......@@ -187,7 +198,7 @@ public class DocumentDidChangeJob extends Job {
jobs.clear();
iAmCurrentlyRunning = false;
CallbackJob cb = new CallbackJob(myEditor, jobStatusList);
CallbackJob cb = new CallbackJob(editor, jobStatusList);
cb.setSystem(true);
cb.schedule();
......@@ -214,39 +225,6 @@ public class DocumentDidChangeJob extends Job {
}
}
class ParserResultJob extends UIJob {
private ParserResult parserResult;
private CupContext context;
@SuppressWarnings("unused")
private long parserModelRevisionNumber;
public ParserResultJob(ParserResult result, CupContext context,
long revisionNumber) {
super("Parser Result UI Job");
this.context = context;
this.parserResult = result;
this.parserModelRevisionNumber = revisionNumber;
}
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
IDocumentProvider provider = myEditor.getDocumentProvider();
if (provider != null) {
IDocument document = provider.getDocument(myEditor
.getEditorInput());
if (document != null) {
Model model = Model.getInstanceForDocument(document);
model.setASTModel(this.parserResult, context, revNumber);
return Status.OK_STATUS;
}
}
return Status.CANCEL_STATUS;
}
}
class SetupJob extends UIJob {
private DocumentDidChangeJob documentDidChangeJob;
......@@ -258,7 +236,7 @@ public class DocumentDidChangeJob extends Job {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
Controller controller = Controller.getInstance(myEditor);
Controller controller = Controller.getInstance(editor);
if (documentDidChangeJob.documentEvents == null
|| documentDidChangeJob.documentEvents.isEmpty()) {
......@@ -275,10 +253,10 @@ public class DocumentDidChangeJob extends Job {
documentDidChangeJob.jobs.addAll(controller.popJobsToDo());
}
jobStatusList.clear();
if (myEditor == null)
if (editor == null)
return Status.CANCEL_STATUS;
IDocument document = myEditor.getDocument();
IDocument document = editor.getDocument();
if (revNumber != RevisionManager.get(document))
return Status.CANCEL_STATUS;
......
......@@ -14,7 +14,7 @@ import de.tum.in.www2.cupplugin.model.Model;
public class LaLrResultJob extends UIJob {
private LALRResult lalrResult;
private long lalrResulRevisionNumber;
private long lalrResultRevisionNumber;
private CupContext lalrContext;
private CupTextEditor editor;
......@@ -23,7 +23,7 @@ public class LaLrResultJob extends UIJob {
super("LaLr Result UI Job");
this.editor = editor;
this.lalrResult = result;
this.lalrResulRevisionNumber = revisionNumber;
this.lalrResultRevisionNumber = revisionNumber;
this.lalrContext = context;
}
......@@ -32,8 +32,9 @@ public class LaLrResultJob extends UIJob {
IDocument document = editor.getDocument();
if (document != null) {
Model model = Model.getInstanceForDocument(document);
model.setLaLrResultModel(this.lalrResult, lalrResulRevisionNumber,
model.setLaLrResultModel(this.lalrResult, lalrResultRevisionNumber,
lalrContext);
model.setStatistics(lalrContext.getStatistics(), lalrResultRevisionNumber);
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
......
package de.tum.in.www2.cupplugin.controller;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.progress.UIJob;
import de.in.tum.www2.cup.CupContext;
import de.in.tum.www2.cup.ast.ParserResult;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.model.Model;
class ParserResultJob extends UIJob {
private CupTextEditor editor;
private ParserResult parserResult;
private CupContext context;
private long parserModelRevisionNumber;
public ParserResultJob(CupTextEditor editor, ParserResult result, CupContext context,
long revisionNumber) {
super("Parser Result UI Job");
this.editor = editor;
this.context = context;
this.parserResult = result;
this.parserModelRevisionNumber = revisionNumber;
}
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
IDocument document = editor.getDocument();
if (document != null) {
Model model = Model.getInstanceForDocument(document);
model.setASTModel(this.parserResult, context, parserModelRevisionNumber);
model.setStatistics(context.getStatistics(), parserModelRevisionNumber);
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
}
}
package de.tum.in.www2.cupplugin.controller;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.progress.UIJob;
import de.in.tum.www2.cup.CupContext;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.model.Model;
class StatisticsIfFailedJob extends UIJob {
private CupTextEditor editor;
private CupContext context;
private long revisionNumber;
public StatisticsIfFailedJob(CupTextEditor editor, CupContext context, long revisionNumber) {
super("Parser Result UI Job");
this.editor = editor;
this.context = context;
this.revisionNumber = revisionNumber;
}
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
IDocument document = editor.getDocument();
if (document != null) {
Model model = Model.getInstanceForDocument(document);
model.setStatistics(context.getStatistics(), revisionNumber);
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
}
}
\ No newline at end of file
......@@ -566,8 +566,7 @@ public class CupContentOutlinePage extends ContentOutlinePage implements
@Override
public void jobStatusChanged(JobStatus status) {
// TODO Auto-generated method stub
// do nothing.
}
}
package de.tum.in.www2.cupplugin.model;
public interface ICupStatisticsChangeObserver {
public void modelChanged(Model model);
}
......@@ -8,6 +8,7 @@ import org.eclipse.jface.text.IDocument;
import de.in.tum.www2.cup.CupContext;
import de.in.tum.www2.cup.LALRResult;
import de.in.tum.www2.cup.Statistics;
import de.in.tum.www2.cup.ast.ParserResult;
public class Model {
......@@ -21,7 +22,10 @@ public class Model {
private LALRResult lalrModel;
private long lalrModelRevisionNumber;
private CupContext lalrContext;
private Statistics statistics;
private final Object statisticsLock = new Object();
private final Object parserModelLock = new Object();
private final Object lalrModellock = new Object();
private List<Object> modelObservers;
......@@ -88,6 +92,23 @@ public class Model {
return astModel;
}
}
public Statistics getStatistics() {
synchronized(statisticsLock) {
return statistics;
}
}
public void setStatistics(Statistics statistics, long revisionNumber) {
synchronized(statisticsLock) {
this.statistics = statistics;
for(Object observer : modelObservers) {
if(observer instanceof ICupStatisticsChangeObserver) {
((ICupStatisticsChangeObserver) observer).modelChanged(this);
}
}
}
}
public void setASTModel(ParserResult result, CupContext context, long revisionNumber) {
synchronized (parserModelLock) {
......@@ -96,7 +117,7 @@ public class Model {
this.astModelRevisionNumber = revisionNumber;
for(Object observer : modelObservers) {
if(observer instanceof ICupParserASTChangeObserver) {
((ICupParserASTChangeObserver)observer).modelChanged(this);
((ICupParserASTChangeObserver) observer).modelChanged(this);
}
}
}
......@@ -131,7 +152,7 @@ public class Model {
this.lalrContext = lalrContext;
for(Object observer : modelObservers) {
if (observer instanceof ICupParserLaLrChangeObserver) {
((ICupParserLaLrChangeObserver)observer).modelChanged(this);
((ICupParserLaLrChangeObserver) observer).modelChanged(this);
}
}
//System.out.println(lalrModel.getReduceTable().toString());
......
......@@ -6,6 +6,8 @@ import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseWheelListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
......@@ -400,32 +402,33 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
updateConflicts(crm);
showMain();
} else {
showError("Parse Tables do not match the current document.");
showParseTablesError();
}
} else {
showError("Parse Tables currently not available.");
showParseTablesError();
matchPanelNumber(0);
}
}
private void showParseTablesError() {
showError("Parse Tables currently not available.");
}
@Override
public void willBecomeVisible() {
this.isVisible = true;
if (!Controller.getInstance(editor).requestJobRun()) {
// the requested job won't run.
System.out.println("NO RERUN!!!"); // TODO
Model model = Model.getInstanceForDocument(editor.getDocument());
handleModelUpdate(model);
} else {
showError("Requested job run ...");
}
}
@Override
public void modelChanged(Model model) {
// TODO: only update if visible?
handleModelUpdate(model);
}
......@@ -444,12 +447,8 @@ public class CupConflictsView extends FailableView implements ICupEditorPageVisi
@Override
public void jobStatusChanged(JobStatus status) {
// TODO: if the job failed, we can show an appropriate error here.
// and update the current status message.
if (status.getAffectedJob() == JobsToDo.buildTable && status.hasFailed())
showParseTablesError();
}
}
package de.tum.in.www2.cupplugin.views;
import java.sql.Time;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.SWT;
......@@ -11,12 +12,15 @@ import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import de.in.tum.www2.cup.ErrorManager;
import de.in.tum.www2.cup.Statistics;
import de.in.tum.www2.cup.ast.ParserResult;
import de.tum.in.www2.cupplugin.Pair;
import de.tum.in.www2.cupplugin.controller.Controller.JobsToDo;
import de.tum.in.www2.cupplugin.controller.Controller;
import de.tum.in.www2.cupplugin.controller.IRegisterForControllerChanges;
......@@ -26,11 +30,45 @@ import de.tum.in.www2.cupplugin.editors.ICupEditorPageVisibility;
import de.tum.in.www2.cupplugin.editors.Jumper;
import de.tum.in.www2.cupplugin.model.ICupParserASTChangeObserver;
import de.tum.in.www2.cupplugin.model.ICupParserLaLrChangeObserver;
import de.tum.in.www2.cupplugin.model.ICupStatisticsChangeObserver;
import de.tum.in.www2.cupplugin.model.Model;
public class CupOverviewView extends FailableView implements IRegisterForControllerChanges,
ICupEditorPageVisibility, ICupParserLaLrChangeObserver,
ICupParserASTChangeObserver {
public class CupOverviewView extends FailableView
implements IRegisterForControllerChanges,
ICupEditorPageVisibility,
ICupParserLaLrChangeObserver,
ICupParserASTChangeObserver,
ICupStatisticsChangeObserver {
class SimpleTable {
private List<Label> labels;
private List<Label> values;
public void setRowValue(int index, int val) {
values.get(index).setText("" + val);
}
public void setRowValue(int index, String val) {
values.get(index).setText(val);
}
public void setRowLabel(int index, String val) {
labels.get(index).setText(val);
}
public SimpleTable() {
labels = new ArrayList<Label>();
values = new ArrayList<Label>();
}
public void addRow(Label label, Label val) {
labels.add(label);
values.add(val);
}
}
private static final int ERROR_ROW = 2;
private static final int OUTER_MARGIN = 10;
private static final int INNER_MARGIN = 10;
......@@ -48,39 +86,61 @@ public class CupOverviewView extends FailableView implements IRegisterForControl
private static final String SECTION_CONFLICTS = "Conflicts";
private static final String SECTION_CONFLICTS_DESCRIPTION_TEMPLATE = "Number of conflicts, etc.";
private Pair<Composite,SimpleTable> analysisSection;
boolean visible = false;
private IDocument doc;
private FormToolkit toolkit;
private ScrolledForm form;
private CupTextEditor myEditor;
HashSet<Composite> sections = new HashSet<Composite>();
private CupTextEditor editor;
public CupOverviewView(Composite realParent, Jumper jumper, IDocument doc,
String title, CupTextEditor editor) {
super(realParent);
Composite parent = getMain();
this.doc = doc;
setupForm(parent, title);
myEditor = editor;
this.editor = editor;
Controller.getInstance(editor).registerObserver(this);
Model.getInstanceForDocument(doc).registerModelObserver(this);
sections.add(createSection(SECTION_ANALYSIS,
SECTION_ANALYSIS_DESCRIPTION_TEMPLATE, false));
sections.add(createSection(SECTION_PARSE_TABLES,
SECTION_PARSE_TABLES_DESCRIPTION_TEMPLATE, false));
sections.add(createSection(SECTION_CONTENT,
SECTION_CONTENT_DESCRIPTION_TEMPLATE, true));
sections.add(createSection(SECTION_GRAMMAR,
SECTION_GRAMMAR_DESCRIPTION_TEMPLATE, false));
sections.add(createSection(SECTION_CONFLICTS,
SECTION_CONFLICTS_DESCRIPTION_TEMPLATE, false));
analysisSection = createTableSection(SECTION_ANALYSIS,
SECTION_ANALYSIS_DESCRIPTION_TEMPLATE, false, 10);
analysisSection.getSecond().setRowLabel(ERROR_ROW, "Errors:");
createSection(SECTION_PARSE_TABLES,
SECTION_PARSE_TABLES_DESCRIPTION_TEMPLATE, false);
createSection(SECTION_CONTENT,
SECTION_CONTENT_DESCRIPTION_TEMPLATE, true);
createSection(SECTION_GRAMMAR,
SECTION_GRAMMAR_DESCRIPTION_TEMPLATE, false);
createSection(SECTION_CONFLICTS,
SECTION_CONFLICTS_DESCRIPTION_TEMPLATE, false);
}
private Pair<Composite,SimpleTable> createTableSection(String title, String description, boolean doSpan, int rowCount) {
Composite section = createSection(title, description, doSpan);
SimpleTable tbl = new SimpleTable();
GridLayout gl = new GridLayout();
gl.numColumns = 2;
section.setLayout(gl);
for (int i=0; i < rowCount; i++) {
Label label = new Label(section, SWT.NONE);
label.setText("TODO");
Label val = new Label(section, SWT.NONE);
val.setText("TODO");
tbl.addRow(label, val);
}
return new Pair<Composite,SimpleTable>(section, tbl);
}
private Composite createSection(String title, String description,
boolean doSpan) {
Section section = toolkit.createSection(form.getBody(),
......@@ -103,7 +163,6 @@ public class CupOverviewView extends FailableView implements IRegisterForControl
client.setLayout(layout);
section.setClient(client);
return client;
}
private void setupForm(Composite parent, String title) {
......@@ -132,7 +191,7 @@ public class CupOverviewView extends FailableView implements IRegisterForControl
public void willBecomeVisible() {
System.out.println("CupOverviewView will become visible.");
visible = true;
if (!Controller.getInstance(myEditor).requestJobRun()) {
if (!Controller.getInstance(editor).requestJobRun()) {
// TODO: Handle no rerun!!