Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 49f3ff48c1951efcc894ebbb96e6842a614c5d18 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*******************************************************************************
 * Copyright (c) 2009 R.Dvorak 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:
 *     Radek Dvorak - initial API and implementation
 *******************************************************************************/
/**
 * 
 */
package org.eclipse.m2m.qvt.oml.debug.core.vm;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.m2m.internal.qvt.oml.ast.binding.ASTBindingHelper;
import org.eclipse.m2m.internal.qvt.oml.common.util.LineNumberProvider;
import org.eclipse.m2m.internal.qvt.oml.expressions.Module;
import org.eclipse.m2m.qvt.oml.debug.core.QVTODebugCore;
import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.BlockExp;
import org.eclipse.ocl.expressions.LoopExp;
import org.eclipse.ocl.expressions.OCLExpression;
import org.eclipse.ocl.utilities.ASTNode;

class IterateBreakpointHelper {

	private final Set<VMBreakpoint> fBreakpoints;
	private final VMBreakpointManager fBPM;

	IterateBreakpointHelper(VMBreakpointManager breakpointManager) {
		fBPM = breakpointManager;
		fBreakpoints = new HashSet<VMBreakpoint>();
	}
	
	VMBreakpoint stepIterateElement(LoopExp<EClassifier, ?> element, UnitLocation currentLocation) {			
		Module currentModule = currentLocation.getModule();

		LineNumberProvider lineNumProvider = getLineNumberProvider(currentModule);
		if(lineNumProvider == null) {
			return null;
		}

		OCLExpression<EClassifier> body = element.getBody();
		if (body == null) {
			return null;
		}

		int bodyLine = lineNumProvider.getLineNumber(body.getStartPosition());
		int elementLine = lineNumProvider.getLineNumber(element.getStartPosition());

		ASTNode iterateBreakpointedElement = body;

		// ensure we can suspend after stepping within iterator if it's body
		// is spread across multiple lines
		if (body instanceof BlockExp) {
			BlockExp blockExp = (BlockExp) body;
			int bodyEndLine = lineNumProvider.getLineNumber(blockExp.getEndPosition());
			if ((bodyEndLine == elementLine) || blockExp.getBody().isEmpty()) {
				return null;
			}
			
			iterateBreakpointedElement = blockExp.getBody().get(0);
		} else if (bodyLine == elementLine) {
			return null;
		}


		URI unitURI = currentLocation.getURI();
		VMBreakpoint breakpoint = createIterateBreakpoint(unitURI,
				iterateBreakpointedElement, elementLine);

		return breakpoint;
	}		

	boolean isIterateBreakpoint(VMBreakpoint breakpoint) {
		return fBreakpoints.contains(breakpoint);
	}

	VMBreakpoint createIterateBreakpoint(URI unitURI, ASTNode breakpointedElement, int line) {
		VMBreakpoint breakpoint = null;
		try {
			breakpoint = fBPM.createVMPrivateBreakpoint(unitURI, breakpointedElement, line, false);
			fBreakpoints.add(breakpoint);
		} catch (CoreException e) {
			QVTODebugCore.log(e.getStatus());
		}
		return breakpoint;
	}

	void removeIterateBreakpoint(VMBreakpoint breakpoint) {
		fBPM.removeBreakpoint(breakpoint);
		fBreakpoints.remove(breakpoint);
	}

	void removeAllIterateBreakpoints() {
		for (VMBreakpoint brk : fBreakpoints) {
			fBPM.removeBreakpoint(brk);
		}
		
		fBreakpoints.clear();
	}
	
    private LineNumberProvider getLineNumberProvider(Module module) {
    	return ASTBindingHelper.getModuleSourceBinding(module).getLineNumberProvider();
    }	
}

Back to the top