/******************************************************************************* * Copyright © 2012, 2013 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.edt.debug.core.java; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Represents the parsed SMAP line mappings, for both directions of mappings. This is only used when the target VM does not support JSR-45 * (SourceDebugExtension). When JSR-45 support is available, JDT does all this work for us. */ public class SMAPLineInfo { /** * EGL lines map to one or more Java lines. */ private final Map<Integer, List<Integer>> eglToJavaLines; /** * Java lines map to one EGL line. */ private final Map<Integer, Integer> javaToEGLLines; public SMAPLineInfo() { this.eglToJavaLines = new HashMap<Integer, List<Integer>>(); this.javaToEGLLines = new HashMap<Integer, Integer>(); } /** * @param eglLine The EGL line to look up. * @return the list of Java lines that maps to the EGL line, or null if there is no mapping. */ public List<Integer> getJavaLines( int eglLine ) { return this.eglToJavaLines.get( eglLine ); } /** * @param eglLine The EGL line to look up. * @return the first Java line that maps to the EGL line, or -1 if there is no mapping. */ public int getFirstJavaLine( int eglLine ) { List<Integer> javaLines = this.eglToJavaLines.get( eglLine ); if ( javaLines == null || javaLines.size() == 0 ) { return -1; } return javaLines.get( 0 ); } /** * @param javaLine The Java line to look up. * @return the corresponding EGL line, or -1 if there is no mapping. */ public int getEGLLine( int javaLine ) { if ( javaToEGLLines.containsKey( javaLine ) ) { return javaToEGLLines.get( javaLine ); } return -1; } /** * Given the SMAP line entry attributes, this calculates the line mappings. * * @param repeatCount The repeat count of the source lines. * @param eglStartLine The start of the source lines. * @param javaStartLine The start of the output lines. * @param javaLineIncrement The increment of the output lines (number of output lines per source line). */ public void addMappings( int repeatCount, int eglStartLine, int javaStartLine, int javaLineIncrement ) { for ( int i = 0; i < repeatCount; i++ ) { boolean fastAdd = false; List<Integer> javaLines = eglToJavaLines.get( eglStartLine + i ); if ( javaLines == null ) { javaLines = new ArrayList<Integer>(); eglToJavaLines.put( eglStartLine + i, javaLines ); fastAdd = true; } int nextJavaLineStart = javaStartLine + (i * javaLineIncrement); for ( int j = 0; j < javaLineIncrement || (j == 0 && javaLineIncrement == 0); j++ ) // increment of 0 is valid and means '1 line' { if ( fastAdd || !javaLines.contains( nextJavaLineStart + j ) ) { javaLines.add( nextJavaLineStart + j ); } if ( !javaToEGLLines.containsKey( nextJavaLineStart + j ) ) { javaToEGLLines.put( nextJavaLineStart + j, eglStartLine + i ); } } } } }