Commit a45e9e2f authored by Johannes Roith's avatar Johannes Roith

Basic fixes for Debugger. Seems to work now. Need to be cleaned up.

parent c93df143
......@@ -2,6 +2,7 @@ package de.tum.in.www2.cupplugin;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
......@@ -15,7 +16,11 @@ import de.tum.in.www2.cupplugin.model.Model;
public class GeneratedFileLocator {
private IFile currentFile;
private WeakHashMap<String,IFile> currentTargetFile;
public GeneratedFileLocator () {
currentTargetFile = new WeakHashMap<String,IFile>();
}
private void scanResources(List<IFile> candidates,
String filename, IContainer parent) throws CoreException {
......@@ -38,6 +43,7 @@ public class GeneratedFileLocator {
return null;
List<IFile> candidates = new ArrayList<IFile>();
IProject project = cupFile.getProject();
System.err.println("Searching in project : " + project.getName());
String className = "Parser";
if (result.className != null) {
Name name = result.className.getName();
......@@ -56,24 +62,26 @@ public class GeneratedFileLocator {
}
public IFile find(IFile cupFile, ParserResult result) {
if (currentFile != null && currentFile.exists()) {
String fullPath = cupFile.getFullPath().toString();
if (currentTargetFile.containsKey(fullPath)) {
IFile currentFile = currentTargetFile.get(fullPath);
// System.out.println("cached!");
return currentFile;
} else {
currentFile = null;
currentTargetFile.remove(fullPath);
}
List<IFile> candidates = findCandidates(cupFile, result);
// if (candidates.size() == 0)
// System.out.println("Found no candidates!");
for (IFile candidate : candidates) {
System.out.println("candidate: " + candidate.getName());
if (currentFile != null) {
if (currentTargetFile.containsKey(fullPath)) {
// TODO: check if better than candidate.
// e.g. if package matches
}
currentFile = candidate;
currentTargetFile.put(fullPath, candidate);
}
return currentFile;
return currentTargetFile.get(fullPath);
}
}
package de.tum.in.www2.cupplugin.controller;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.internal.core.util.WeakHashSet;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITypedRegion;
......@@ -51,7 +54,8 @@ public class Controller {
private long currentRevisionNumber = 0;
private List<IRegisterForControllerChanges> controllerObservers;
private Set<IRegisterForControllerChanges> controllerObservers = Collections.newSetFromMap(
new WeakHashMap<IRegisterForControllerChanges, Boolean>());
/*
* Static singleton getter
......@@ -92,8 +96,7 @@ public class Controller {
myJob = new DocumentDidChangeJob(editor);
myJob.setSystem(true);
documentEvents = new LinkedList<DocumentEvent>();
Debugger.getInstance(editor);
controllerObservers = new LinkedList<IRegisterForControllerChanges>();
Debugger.getInstance(myEditor.getDocument()); // TODO: why is this here?
}
public void addDocumentEvent(DocumentEvent e) {
......@@ -143,6 +146,12 @@ public class Controller {
}
}
public void unregisterObserver(IRegisterForControllerChanges observer) {
synchronized (controllerObservers) {
controllerObservers.remove(observer);
}
}
/*
* notify method that's to be called, when a change in the document happens
*/
......
......@@ -18,6 +18,9 @@ import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;
import org.eclipse.ui.texteditor.IDocumentProvider;
import de.in.tum.www2.cup.analysis.GetDebuggerMappingVisitor.Mapping;
import de.in.tum.www2.cup.ast.ParserResult;
......@@ -28,78 +31,106 @@ public class BreakpointMapper {
private Map<CupLineBreakpoint, IBreakpoint> mappings = new HashMap<CupLineBreakpoint, IBreakpoint>();
private Set<CupLineBreakpoint> breakpoints = new HashSet<CupLineBreakpoint>();
private GeneratedFileLocator locator = new GeneratedFileLocator();
public IBreakpoint getRemoteBreakpoint(CupLineBreakpoint breakpoint) {
return mappings.get(breakpoint);
}
public CupLineBreakpoint getOrigin(IBreakpoint breakpoint) {
for (Map.Entry<CupLineBreakpoint, IBreakpoint> e : mappings.entrySet()) {
if (e.getValue().equals(breakpoint)) {
if (e.getValue().equals(breakpoint))
return e.getKey();
}
}
return null;
}
protected void addRemoteBreakpoint(CupLineBreakpoint origin) {
IJavaLineBreakpoint remote = null;
private void addRemoteBreakpoint(CupLineBreakpoint origin) {
IResource originResource = origin.getMarker().getResource();
System.err.println(">>>>> CALLING FOR " + origin.getResource());
System.err.println(">>>>> CALLING FOR getResource " + originResource);
IDocument document = null;
if (originResource instanceof IDocument) {
document = (IDocument) originResource;
} else if (originResource instanceof IFile) {
IFile file = (IFile) originResource;
// TODO: this is not efficient !!!!!!!!!!!!!!
IDocumentProvider provider = new TextFileDocumentProvider();
try {
provider.connect(file);
} catch (CoreException e) {
e.printStackTrace();
}
document = provider.getDocument(file);
} else {
throw new RuntimeException("Unexpected resource type.");
}
Debugger dbg = Debugger.getInstance(document);
System.out.println(">>>>>>>>> originResource: " + originResource);
IResource originResource = origin.getMarker().getResource();
if(originResource == null){
if(originResource == null)
return;
}
ParserResult astModel = Debugger.getInstance(originResource).getParserResult();
if(astModel == null){
ParserResult astModel = dbg.getParserResult();
if(astModel == null)
return;
}
System.out.println("-------- begin locator");
IFile resource = locator.find((IFile) originResource, astModel);
System.out.println("-------- end locator");
if(resource == null){
if(resource == null)
return;
}
Map<String, Object> attributes = new HashMap<String, Object>();
BufferedReader reader;
try {
reader = new BufferedReader(new InputStreamReader(resource.getContents()));
} catch (CoreException e1) {
e1.printStackTrace();
return;
}
SimpleDebugLineMatcher lineMatcher = new SimpleDebugLineMatcher(reader);
List<Integer> debugIds = new LinkedList<Integer>();
int originLineNumber = origin.getMarker().getAttribute(IMarker.LINE_NUMBER, -1);
if(originLineNumber == -1){
if(originLineNumber == -1)
return;
}
Mapping debugId = Debugger.getInstance(originResource).getDebugId(originLineNumber);
if(debugId == null){
Mapping debugId = dbg.getDebugId(originLineNumber);
if(debugId == null)
return;
}
debugIds.add(debugId.getDebugId());
int remoteLineNumber = lineMatcher.debuggerFindCase(debugIds).get(0) + debugId.getLineOffsetFromId();
if(remoteLineNumber == -1){
doCreateTargetBreakpoint(origin, document, resource, remoteLineNumber);
}
private void doCreateTargetBreakpoint(CupLineBreakpoint origin, IDocument doc, IFile remoteFile, int remoteLineNumber) {
if(remoteLineNumber == -1)
return;
}
//remoteLineNumber = 5;//TODO nur zum testen
System.err.println("CREATING REMOTE BREAKPOINT for " +
origin.getResource() + " at remote file " +
remoteFile + " line : " + remoteLineNumber);
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(IBreakpoint.PERSISTED, false);
if (resource != null) {
IJavaLineBreakpoint remote = null;
if (remoteFile != null) {
try {
// targetClass
String targetClass = Debugger.getInstance(doc).getGeneratedTargetClass(origin);
remote = JDIDebugModel.createLineBreakpoint(resource,
Debugger.getInstance(originResource).getGeneratedTargetClass(origin), remoteLineNumber, -1, -1, 0,
System.out.println("targetClass: " + targetClass);
remote = JDIDebugModel.createLineBreakpoint(remoteFile,
targetClass, remoteLineNumber, -1, -1, 0,
true, attributes);
remote.setEnabled(true);
DebugPlugin.getDefault().getBreakpointManager()
.addBreakpoint(remote);
remote.isInstalled();
......@@ -112,11 +143,9 @@ public class BreakpointMapper {
}
mappings.put(origin, remote);
}
}
protected static boolean removeRemoteBreakpoint(IBreakpoint breakpoint) {
try {
DebugPlugin.getDefault().getBreakpointManager()
.removeBreakpoint(breakpoint, true);
......@@ -127,41 +156,37 @@ public class BreakpointMapper {
}
public void add(CupLineBreakpoint breakpoint) {
System.err.println(">>>>> ADDING " + breakpoint.getResource());
breakpoints.add(breakpoint);
remap();
}
public void remove(CupLineBreakpoint breakpoint) {
breakpoints.remove(breakpoint);
remap();
}
public void change(CupLineBreakpoint breakpoint) {
remap();
}
protected void removeAll() {
for (IBreakpoint breakpoint : mappings.values()) {
removeRemoteBreakpoint(breakpoint);
}
}
protected void addAll() {
for (CupLineBreakpoint breakpoint : breakpoints) {
addRemoteBreakpoint(breakpoint);
}
}
public void remap() {
removeAll();
addAll();
}
}
package de.tum.in.www2.cupplugin.debug;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import de.tum.in.www2.cupplugin.controller.Controller.JobsToDo;
import de.tum.in.www2.cupplugin.editors.CupEditorErrorReporter;
import de.tum.in.www2.cupplugin.editors.CupTextEditor;
import de.tum.in.www2.cupplugin.editors.RevisionManager;
import de.tum.in.www2.cupplugin.model.Model;
import de.in.tum.www2.cup.CupParser;
import de.in.tum.www2.cup.NoopErrorReporter;
import de.in.tum.www2.cup.analysis.FindNextCodeBlockLineVisitor;
import de.in.tum.www2.cup.analysis.GetDebuggerMappingVisitor;
import de.in.tum.www2.cup.analysis.GetDebuggerMappingVisitor.Mapping;
import de.in.tum.www2.cup.ast.ClassName;
import de.in.tum.www2.cup.ast.ParserResult;
public class Debugger {
static final String DEBUG_ID = "de.tum.www2.cupplugin.debug.Debugger";
// Static reference to the controller instance per document
static HashMap<CupTextEditor, Debugger> instances = new HashMap<CupTextEditor, Debugger>();
static HashMap<IResource, Debugger> delayedInstances = new HashMap<IResource, Debugger>();
static HashMap<IDocument, Debugger> instances = new HashMap<IDocument, Debugger>();
// static HashMap<IResource, Debugger> delayedInstances = new HashMap<IResource, Debugger>();
private static final BreakpointMapper breakpointMapper = new BreakpointMapper();
private static final String DEFAULT_CLASS = "Parser";
......@@ -41,18 +52,19 @@ public class Debugger {
// attributes
// the document, the instance is managing
private CupTextEditor myEditor = null;
// private CupTextEditor myEditor = null;
private IDocument document = null;
private static IBreakpointManager DefaultBreakPointManager = null;
/*
* Static singelton getter
*/
public static Debugger getInstance(CupTextEditor editor) {
Debugger instance = instances.get(editor);
public static Debugger getInstance(IDocument document) {
System.out.println("GETTING DEBUGGER INSTANCE FOR: " + document);
Debugger instance = instances.get(document);
if (instance != null) {
/*
if (!instances.isEmpty()) {
for (Map.Entry<CupTextEditor, Debugger> e : instances
for (Map.Entry<IDocument, Debugger> e : instances
.entrySet()) {
IEditorInput input = e.getKey().getEditorInput();
if (input == null) {
......@@ -64,12 +76,11 @@ public class Debugger {
delayedInstances.remove(resource);
}
}
}
}*/
return instance;
} else {
instances.put(editor, new Debugger(editor));
return instances.get(editor);
instances.put(document, new Debugger(document));
return instances.get(document);
}
}
......@@ -77,9 +88,10 @@ public class Debugger {
return breakpointMapper;
}
/*
public static Debugger getInstance(IResource resource) {
IResource current = null;
for (Map.Entry<CupTextEditor, Debugger> e : instances.entrySet()) {
for (Map.Entry<IDocument, Debugger> e : instances.entrySet()) {
IEditorInput input = e.getKey().getEditorInput();
if (input != null) {
current = (IResource) input.getAdapter(IResource.class);
......@@ -93,17 +105,25 @@ public class Debugger {
}
current = null;
}
Debugger tmp = new Debugger(new CupTextEditor());// TODO: lösen
delayedInstances.put(resource, tmp);
return tmp;
//IDocumentProvider provider = new TextFileDocumentProvider();
//provider.connect(ifile);
//document = provider.getDocument(ifile);
throw new RuntimeException("CUP EDITOR NOT FOUND!");
//Debugger tmp = new Debugger(new CupTextEditor());// TODO: lösen
//delayedInstances.put(resource, tmp);
//return tmp;
}
*/
/*
* The Constructor, taking the document it's controlling as a parameter
*/
public Debugger(CupTextEditor editor) {
myEditor = editor;
public Debugger(IDocument document) {
this.document = document;
DefaultBreakPointManager = DebugPlugin.getDefault()
.getBreakpointManager();
BreakpointListener.getInstance();
......@@ -127,15 +147,14 @@ public class Debugger {
*/
public int getNextCodeBlockForLineBreakpoint(int line) {
Model m = Model.getInstanceForDocument(myEditor.getDocument());
ParserResult astModel = m.getAstModel();
if (astModel == null)
ParserResult astModel = getParserResult();
if (astModel == null) {
System.err.println("WARNING: did not use breakpoint snapping, because AST was not available.");
return line;
}
// create Visitor
FindNextCodeBlockLineVisitor v = new FindNextCodeBlockLineVisitor(line);
astModel.accept(v, null);
return v.getResult();
}
......@@ -149,44 +168,82 @@ public class Debugger {
* @return the class name
*/
public String getGeneratedTargetClass(CupLineBreakpoint breakpoint) {
ParserResult result = getParserResult();
try {
String rname = getParserResult().className.getName().name;
if (!rname.trim().equals("")) {
return rname;
}
} catch (NullPointerException e) {
if (result == null) {
System.err.println("WARNING: No AST available. Using default class. Debugger may not work.");
return DEFAULT_CLASS;
}
String packageName = null;
if (result.pack != null)
packageName = result.pack.getNameStringOrNull();
if (packageName == null) {
System.err.println("WARNING: No package specified in cup file. Debugger might not work.");
packageName = "";
} else {
packageName += ".";
}
return DEFAULT_CLASS;
ClassName className = result.className;
if (className != null) {
String rname = className.getNameStringOrNull();
if (!rname.trim().equals(""))
return packageName + rname;
}
return packageName + DEFAULT_CLASS;
}
public Mapping getDebugId(int lineNumber) {
ParserResult astModel = getParserResult();
if (astModel == null) {
if (astModel == null)
return null;
}
// TODO: this is too expensive! -> pass all line numbers in array!
// create Visitor
int lines[] = {lineNumber};
int lines[] = { lineNumber };
GetDebuggerMappingVisitor v = new GetDebuggerMappingVisitor(lines);
astModel.accept(v, null);
if(v.getMappings().size() < 1){
return null;
}
return v.getMappings().get(0);
}
public ParserResult getParserResult(){
if(myEditor == null){
System.out.println("myEditor: NULL");
private ParserResult selfBuiltAstCache;
public ParserResult getParserResult() {
if(document == null)
System.out.println("document: NULL");
if (!CupTextEditor.hasOpened(document)) {
// If the document is not opened in a text editor,
// we need to create the parser result ourselves.
if (selfBuiltAstCache != null)
return selfBuiltAstCache;
InputStream in = new ByteArrayInputStream(document.get().getBytes());
CupParser parser = new CupParser(new NoopErrorReporter(), in);
try {
selfBuiltAstCache = parser.parse();
// TODO: manage revisions properly?
long revision = RevisionManager.increment(document);
Model.getInstanceForDocument(document).setASTModel(selfBuiltAstCache, revision);
} catch (Exception e1) {
e1.printStackTrace();
}
return selfBuiltAstCache;
} else {
Model m = Model.getInstanceForDocument(document);
ParserResult astModel = m.getAstModel();
return astModel;
}
Model m = Model.getInstanceForDocument(myEditor.getDocument());
ParserResult astModel = m.getAstModel();
return astModel;
}
}
\ No newline at end of file
......@@ -39,7 +39,7 @@ public class ToggleBreakpointsTarget implements IToggleBreakpointsTarget {
ITextSelection textSelection = (ITextSelection) selection;
int lineNumber = textSelection.getStartLine();
int nextPossibleLine = (Debugger
.getInstance((CupTextEditor) textEditor)
.getInstance(((CupTextEditor) textEditor).getDocument())
.getNextCodeBlockForLineBreakpoint(((ITextSelection) selection)
.getStartLine()));
if (nextPossibleLine != -1) {
......@@ -56,7 +56,7 @@ public class ToggleBreakpointsTarget implements IToggleBreakpointsTarget {
if (doc == null) {
return;
}
// create preakpoint and give it to IDE
// create breakpoint and give it to IDE
IBreakpoint[] breakpoints = (IBreakpoint[]) Debugger
.getBreakpointManager().getBreakpoints();
......@@ -92,7 +92,7 @@ public class ToggleBreakpointsTarget implements IToggleBreakpointsTarget {
// true, if we have an CupTextEditor
if (part instanceof CupTextEditor) {
if (selection instanceof ITextSelection) {
return (Debugger.getInstance((CupTextEditor) part)
return (Debugger.getInstance(((CupTextEditor) part).getDocument())
.getNextCodeBlockForLineBreakpoint(
((ITextSelection) selection).getStartLine()) != -1);
} else {
......@@ -110,7 +110,7 @@ public class ToggleBreakpointsTarget implements IToggleBreakpointsTarget {
if (editor instanceof CupTextEditor) {
if (selection instanceof ITextSelection) {
return (Debugger
.getInstance((CupTextEditor) editor)
.getInstance(((CupTextEditor) editor).getDocument())
.getNextCodeBlockForLineBreakpoint(
((ITextSelection) selection).getStartLine()) != -1);
} else {
......
package de.tum.in.www2.cupplugin.editors;
import java.util.EnumSet;
import java.util.HashSet;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.ui.actions.ToggleBreakpointAction;
......@@ -33,6 +34,8 @@ import de.tum.in.www2.cupplugin.model.Model;
public class CupTextEditor extends TextEditor
implements ICupParserASTChangeObserver, IRegisterForControllerChanges
{
public static HashSet<IDocument> hasOpened = new HashSet<IDocument>();
IVerticalRulerInfo ruler = null;
private CupContentOutlinePage outlinePage;
private Position lastPosition;
......@@ -82,8 +85,9 @@ public class CupTextEditor extends TextEditor
super();
setSourceViewerConfiguration(new CupSourceViewerConfiguration(this));
}
public void init() {
hasOpened.add(getDocument());
getModel().registerModelObserver(this);
Controller.getInstance(this).registerObserver(this);
}
......@@ -112,6 +116,10 @@ public class CupTextEditor extends TextEditor
return null;
}
public static boolean hasOpened(IDocument document) {
return hasOpened.contains(document);
}
// adapted from http://javadude.googlecode.com/svn/trunk/com.javadude.antxr.eclipse.ui/src/com/javadude/antxr/eclipse/ui/editor/AntxrEditor.java
public Position getCursorPos() {
int caret = -1;
......@@ -175,12 +183,13 @@ public class CupTextEditor extends TextEditor
@Override
public void dispose() {
IDocumentProvider p = getDocumentProvider();
IEditorInput input = getEditorInput();
if (p != null && input != null) {
IDocument doc = p.getDocument(input);
Model.deleteForDocument(doc);
}
System.out.println(">>>>>>>>>> DISPOSING EDITOR!");
IDocument doc = getDocument();
hasOpened.remove(doc);
Model.deleteForDocument(doc);
Controller.getInstance(this).unregisterObserver(this);
super.dispose();
}
......@@ -217,7 +226,6 @@ public class CupTextEditor extends TextEditor
getVerticalRuler());
manager.add(tba);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment