blob: b4e8646e193bb79f9a40d4d6760aa42086a332aa [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2010, 2011 Nokia 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:
* Nokia - Initial API and implementation
* Broadcom - use toHexAddress in CompileUnitScope as used elsewhere
*******************************************************************************/
package org.eclipse.cdt.debug.edc.internal.symbols;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.edc.symbols.ICompileUnitScope;
import org.eclipse.cdt.debug.edc.symbols.IFunctionScope;
import org.eclipse.cdt.debug.edc.symbols.ILineEntry;
import org.eclipse.cdt.debug.edc.symbols.IModuleScope;
import org.eclipse.cdt.debug.edc.symbols.IScope;
import org.eclipse.core.runtime.IPath;
/**
* Scope extension implementing ICompileUnitScope, with:<br>
* CompileUnitScope specific filePath and line-entries
*/
public abstract class CompileUnitScope extends Scope implements ICompileUnitScope {
protected IPath filePath;
protected Collection<ILineEntry> lineEntries;
public CompileUnitScope(IPath filePath, IModuleScope parent, IAddress lowAddress, IAddress highAddress) {
super(filePath != null ? filePath.lastSegment() : "", lowAddress, highAddress, parent); //$NON-NLS-1$
this.filePath = filePath;
}
public IPath getFilePath() {
return filePath;
}
public IFunctionScope getFunctionAtAddress(IAddress linkAddress) {
IScope scope = getScopeAtAddress(linkAddress);
while (scope != null && !(scope instanceof IFunctionScope)) {
scope = scope.getParent();
}
return (IFunctionScope) scope;
}
public Collection<IFunctionScope> getFunctions() {
List<IFunctionScope> functions = new ArrayList<IFunctionScope>(children.size());
for (IScope scope : getChildren()) {
if (scope instanceof IFunctionScope)
functions.add((IFunctionScope) scope);
}
return Collections.unmodifiableCollection(functions);
}
/**
* Parse the line table data - to be implemented by debug format specific
* sub classes.
*
* @return the list of line table entries (may be empty)
*/
protected abstract Collection<ILineEntry> parseLineTable();
public Collection<ILineEntry> getLineEntries() {
if (lineEntries == null) {
lineEntries = parseLineTable();
}
return Collections.unmodifiableCollection(lineEntries);
}
/**
* CompileUnitScope specific version of toString():<br>
* <code>
* [lowAddress=, highAddress=, path=]
* </code>
* @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#toString()
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("CompileUnitScope ["); //$NON-NLS-1$
builder.append("lowAddress="); //$NON-NLS-1$
builder.append(lowAddress != null ? lowAddress.toHexAddressString() : null);
builder.append(", highAddress="); //$NON-NLS-1$
builder.append(highAddress != null ? highAddress.toHexAddressString() : null);
builder.append(", "); //$NON-NLS-1$
if (filePath != null) {
builder.append("path="); //$NON-NLS-1$
builder.append(filePath.toOSString());
builder.append(", "); //$NON-NLS-1$
}
builder.append("]"); //$NON-NLS-1$
return builder.toString();
}
/**
* force extensions of this abstract class to add their own
* debug-info specific info to the hashCode
* @return
* @see CompileUnitScope#hashCode
*/
protected abstract int cuScopeHashCode();
/**
* hashCode() from this level on down is currently here for only one
* purpose: a HashSet&ltICompileUnitScope> maintained by
* {@link org.eclipse.cdt.debug.edc.internal.symbols.ModuleLineEntryProvider}.
* It is made final so nothing below overrides the implementation to include the
* name, and relies on abstract {@link CompileUnitScope#compileScopeHashCode()}
* to force each extension of this abstract class to implement its own
* hashCode() to satisfy the need for a unique hash-id.
*/
@Override
final public int hashCode() {
final int prime = 31;
return name.hashCode() * prime + cuScopeHashCode();
}
/**
* force extensions of this abstract class to add their own
* debug-info specific info to the CompileUnitScope equality test
* @return
* @see CompileUnitScope#equals
*/
protected abstract boolean cuScopeEquals(Object obj);
/**
* equality comparison for use together with the value provided by
* {@link CompileUnitScope#hashCode}. made final here so extensions
* of this class cannot simply override it.
*/
@Override
final public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
if (!name.equals(((Scope)obj).name))
return false;
return cuScopeEquals(obj);
}
}