/*******************************************************************************
* Copyright (c) 2006 Business Objects Software Limited and others.
* All rights reserved.
* This file is 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:
* Business Objects Software Limited - initial API and implementation based on Eclipse 3.1.2 code for
* /org.eclipse.jdt.ui/core extension/org/eclipse/jdt/internal/corext/util/CodeFormatterUtil.java
* Eclipse source is available at: http://www.eclipse.org/downloads/
*******************************************************************************/
/*
* ModuleTreeContentProvider.java
* Creation date: Jan 22 2007
* By: Greg McClement
*/
package org.openquark.cal.eclipse.ui.views;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.openquark.cal.compiler.ClassInstance;
import org.openquark.cal.compiler.ClassMethod;
import org.openquark.cal.compiler.DataConstructor;
import org.openquark.cal.compiler.Function;
import org.openquark.cal.compiler.ModuleName;
import org.openquark.cal.compiler.ModuleSourceDefinition;
import org.openquark.cal.compiler.ModuleTypeInfo;
import org.openquark.cal.compiler.Scope;
import org.openquark.cal.compiler.ScopedEntity;
import org.openquark.cal.compiler.TypeClass;
import org.openquark.cal.compiler.TypeConstructor;
import org.openquark.cal.eclipse.core.CALModelManager;
import org.openquark.cal.eclipse.core.builder.CALBuilder;
import org.openquark.cal.eclipse.ui.CALUIMessages;
import org.openquark.cal.eclipse.ui.util.CoreUtility;
import org.openquark.cal.eclipse.ui.views.CALWorkspace.ModuleElementsByType;
import org.openquark.cal.machine.StatusListener;
/**
* A content provider for the CAL Workspace and the Outline view of CAL files.
*/
public abstract class ModuleTreeContentProvider implements IStructuredContentProvider,
ITreeContentProvider {
/**
* Show the form of the name with the module hierarchy.
*/
private final CALModuleContentProvider moduleContentProvider;
/**
* The root of the viewer. An arbitrary unique object!
*/
private final Object root = new Object ();
private final CALModelManager calModelManager = CALModelManager.getCALModelManager();
private TreeViewer viewer;
// if the cal builder is not enabled then a message saying this is shown. When
// the cal builder is enabled we want to refresh the dialog from scratch and get
// rid of that message.
private boolean calBuilderWasEnabled = true;
/**
* If the tree is flat then the root it a collection of modules. If the tree is structed
* then the root is a HierarchicalNode.
*/
private Object invisibleRoot;
private Map<ModuleName, Object> moduleSourceDefinitionToModuleElementByTypeMap_functions = new HashMap<ModuleName, Object>();
private Map<ModuleName, Object> moduleSourceDefinitionToModuleElementByTypeMap_typeClasses = new HashMap<ModuleName, Object>();
private Map<ModuleName, Object> moduleSourceDefinitionToModuleElementByTypeMap_typeConstructors = new HashMap<ModuleName, Object>();
private Map<ModuleName, Object> moduleSourceDefinitionToModuleElementByTypeMap_classInstances = new HashMap<ModuleName, Object>();
// Actions for controlling the layout content
private Action showClassOfCALElementsAction;
private Action showPrivateElementsAction;
private Action linkWithEditorAction;
private StatusListener compileStatusListener = null;
protected final ILabelProvider labelProvider;
/**
* @param moduleContentProvider The adapter for exchanging information between this content provider and the object that refers to it.
* @param viewer The tree viewer that the content provider is for. This is used to update the view on compiles.
*/
public ModuleTreeContentProvider(CALModuleContentProvider moduleContentProvider, ILabelProvider labelProvider, TreeViewer viewer) {
this.moduleContentProvider = moduleContentProvider;
this.labelProvider = labelProvider;
this.viewer = viewer;
makeActions();
CoreUtility.initializeCALBuilderInBackground();
hookIntoCompiler();
viewer.setComparator(getComparator());
}
private static final ViewerComparator viewerComparator = new ViewerComparator() {
Object adjustName(Object object){
if (object instanceof ClassInstance){
final ClassInstance classInstance = (ClassInstance) object;
return classInstance.getName().replaceFirst("\\(", "");
}
return object;
}
@Override
public int compare(Viewer viewer, Object e1, Object e2){
return super.compare(viewer, adjustName(e1), adjustName(e2));
}
};
public ViewerComparator getComparator(){
return viewerComparator;
}
/**
* Method getRoot
*
* @return Returns the arbitrary root object
*/
public Object getRoot () {
return root;
}
/**
* @return the moduleContentProvider
*/
protected CALModuleContentProvider getModuleContentProvider () {
return moduleContentProvider;
}
/**
* @return the viewer
*/
protected TreeViewer getViewer () {
return viewer;
}
protected boolean wasCalBuilderEnabled () {
return calBuilderWasEnabled;
}
protected void setCalBuilderWasEnabled (boolean value) {
calBuilderWasEnabled = value;
}
protected boolean canLinkWithEditor(){
return true;
}
/**
* @return the invisibleRoot
*/
protected Object getInvisibleRoot () {
return invisibleRoot;
}
public abstract void fillLocalPullDown(IMenuManager manager);
protected void addStandardLocalMenuActions (IMenuManager manager) {
manager.add(showClassOfCALElementsAction);
manager.add(showPrivateElementsAction);
if (canLinkWithEditor()){
manager.add(linkWithEditorAction);
}
}
public abstract void fillContextMenu(IMenuManager manager);
protected void addStandardContextMenuActions (IMenuManager manager) {
manager.add(showClassOfCALElementsAction);
manager.add(showPrivateElementsAction);
if (canLinkWithEditor()){
manager.add(linkWithEditorAction);
}
}
/**
* Depending on if the class of elements are shown add the appropriate object to the start
* of the path to the given object in the tree viewer hierarchy.
* @param scopedEntities A (partial) path to an entity in the tree viewer.
*/
public void augmentPath(LinkedList<Object> scopedEntities){
if (moduleContentProvider.getShowElementHierarchy()){
Object entity = scopedEntities.getFirst();
if (entity instanceof Function){
ModuleName moduleName = ((ScopedEntity) entity).getName().getModuleName();
scopedEntities.addFirst(moduleSourceDefinitionToModuleElementByTypeMap_functions.get(moduleName));
}
else if (entity instanceof TypeClass){
ModuleName moduleName = ((ScopedEntity) entity).getName().getModuleName();
scopedEntities.addFirst(moduleSourceDefinitionToModuleElementByTypeMap_typeClasses.get(moduleName));
}
else if (entity instanceof TypeConstructor){
ModuleName moduleName = ((ScopedEntity) entity).getName().getModuleName();
scopedEntities.addFirst(moduleSourceDefinitionToModuleElementByTypeMap_typeConstructors.get(moduleName));
}
else if (entity instanceof ClassInstance){
ModuleName moduleName = ((ClassInstance) entity).getModuleName();
scopedEntities.addFirst(moduleSourceDefinitionToModuleElementByTypeMap_classInstances.get(moduleName));
}
}
}
public void makeContributions(IToolBarManager toolBarManager){
}
public void makeContributions(IStatusLineManager statusLineManager){
}
protected void setShowModuleHierarchy(boolean showModuleHierarchy){
if (showModuleHierarchy == moduleContentProvider.getShowModuleHierarchy()){
return;
}
else{
ISelection selection = viewer.getSelection();
moduleContentProvider.setShowModuleHierarchy(showModuleHierarchy);
initialize();
viewer.refresh(root);
viewer.setSelection(selection, true);
}
}
private void setShowElementHierarchy(boolean showElementHierarchy){
if (showElementHierarchy == moduleContentProvider.getShowElementHierarchy()){
return;
}
else{
ISelection selection = viewer.getSelection();
moduleContentProvider.setShowElementHierarchy(showElementHierarchy);
initialize();
viewer.refresh(root);
viewer.setSelection(selection, true);
}
}
private void setShowPrivateElements(boolean showPrivateElements){
if (showPrivateElements == moduleContentProvider.getShowPrivateElements()){
return;
}
else{
ISelection selection = viewer.getSelection();
moduleContentProvider.setShowPrivateElements(showPrivateElements);
initialize();
viewer.refresh(root);
viewer.setSelection(selection, true);
}
}
private void makeActions(){
// Show Hierarchy of CAL Elements Action
{
showClassOfCALElementsAction = new Action("", IAction.AS_CHECK_BOX) {
@Override
public void run() {
setShowElementHierarchy(isChecked());
}
};
showClassOfCALElementsAction.setText(CALUIMessages.CALWorkspace_showClassOfCALElements);
showClassOfCALElementsAction.setChecked(moduleContentProvider.getShowElementHierarchy());
showClassOfCALElementsAction.setToolTipText(CALUIMessages.CALWorkspace_showClassOfCALElements_tooltip);
// showClassOfCALElementsAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
// getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
}
// Show Hierarchy of CAL Elements Action
{
showPrivateElementsAction = new Action("", IAction.AS_CHECK_BOX) {
@Override
public void run() {
setShowPrivateElements(isChecked());
}
};
showPrivateElementsAction.setText(CALUIMessages.CALWorkspace_showPrivateElements);
showPrivateElementsAction.setChecked(moduleContentProvider.getShowPrivateElements());
showPrivateElementsAction.setToolTipText(CALUIMessages.CALWorkspace_showPrivateElements_tooltip);
// showPrivateElementsAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
// getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
}
linkWithEditorAction = new Action("", IAction.AS_CHECK_BOX) {
@Override
public void run() {
setLinkWithEditor(isChecked());
}
};
linkWithEditorAction.setText(CALUIMessages.CALWorkspace_linkWithEditor);
linkWithEditorAction.setChecked(getModuleContentProvider ().getLinkWithEditor());
// linkWithEditorAction.setToolTipText(CALUIMessages.CALWorkspace_linkWithEditor_tooltip);
// linkWithEditorAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
// getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
}
private void setLinkWithEditor(boolean linkWithEditor){
getModuleContentProvider ().setLinkWithEditor(linkWithEditor);
}
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
}
public void dispose() {
calModelManager.getProgramModelManager().removeStatusListener(compileStatusListener);
}
/**
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
*
* Only called to retrieve the root elements
*/
public Object[] getElements(Object parent) {
if (parent.equals(root))
return getRootElements ();
return getChildren(parent);
}
/**
* Method getRootElements
*
* @return Returns the top-level elements
*/
abstract protected Object[] getRootElements ();
/*
* This is needed in order to ensure that when the configuration of the viewer is change that
* the same objects that are currently visible will stay visible.
* @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
*/
public Object getParent(Object child) {
if (child instanceof HierarchicalNode){
if (this.moduleContentProvider.getShowModuleHierarchy()){
return ((HierarchicalNode) child).getParent();
}
else{
// no longer has a parent in this configuration
return null;
}
}
else if (child instanceof ModuleName){
if (this.moduleContentProvider.getShowModuleHierarchy()){
// Get the hierachical node that contains this module
HierarchicalNode hn = (HierarchicalNode) invisibleRoot;
return hn.getParent((ModuleName) child);
}
else{
// No structure so the root is the parent
return root;
}
}
else if (child instanceof ScopedEntity){
if (child instanceof DataConstructor){
return ((DataConstructor) child).getTypeConstructor();
}
else if (this.moduleContentProvider.getShowElementHierarchy()){
// ensure the structure is set up
ModuleName moduleName = ((ScopedEntity) child).getName().getModuleName();
getChildren(moduleName);
if (child instanceof Function){
return moduleSourceDefinitionToModuleElementByTypeMap_functions.get(moduleName);
}
else if (child instanceof TypeClass){
return moduleSourceDefinitionToModuleElementByTypeMap_typeClasses.get(moduleName);
}
else if (child instanceof TypeConstructor){
return moduleSourceDefinitionToModuleElementByTypeMap_typeConstructors.get(moduleName);
}
else if (child instanceof ClassInstance){
return moduleSourceDefinitionToModuleElementByTypeMap_typeConstructors.get(moduleName);
}
else{
return null;
}
}
else{
return ((ScopedEntity) child).getName().getModuleName();
}
}
else if (child instanceof ModuleElementsByType){
return ((ModuleElementsByType) child).getParent();
}
else{
return null;
}
}
private Comparator<Object> comparator = new Comparator<Object>() {
public int compare(Object o1, Object o2) {
if (o1 instanceof ScopedEntity){
final ScopedEntity se1 = (ScopedEntity) o1;
if (o2 instanceof ScopedEntity){
ScopedEntity se2 = (ScopedEntity) o2;
// If names compare as equal the model removes them so for "Either" and "either" with
// just a case insensitive compare would cause one of them to be not shown.
// I want all the E's to show up together so I don't want to just switch to a
// case sensitive compare. So let's do a case insensitive compare then a
// case sensitive compare.
final int compare = se1.getName().getUnqualifiedName().compareToIgnoreCase(se2.getName().getUnqualifiedName());
if (compare != 0){
return compare;
}
return se1.getName().getUnqualifiedName().compareTo(se2.getName().getUnqualifiedName());
}
else if (o2 instanceof ClassInstance){
return labelProvider.getText(o1).compareToIgnoreCase(labelProvider.getText(o2));
}
}
else if (o1 instanceof ClassInstance){
return labelProvider.getText(o1).compareToIgnoreCase(labelProvider.getText(o2));
}
return 0;
}
};
private void add(Collection<Object> collection, Object[] objects){
for (final Object element : objects) {
collection.add(element);
}
}
public Object [] getChildren(Object parent) {
return getChildren(parent, false);
}
private Object [] getChildren(Object parent, boolean alwaysGetChildren) {
if (parent instanceof HierarchicalNode){
return ((HierarchicalNode) parent).getChildren();
}
else if (parent instanceof ModuleName){
ModuleName moduleName = (ModuleName) parent;
ModuleTypeInfo mti = calModelManager.getModuleTypeInfo(moduleName);
if (this.moduleContentProvider.getShowElementHierarchy()){
ArrayList<Object> children = new ArrayList<Object>(4);
if (mti != null){
{
Object mebt = moduleSourceDefinitionToModuleElementByTypeMap_functions.get(moduleName);
if (mebt == null){
if (mti.getNFunctions() > 0){
SortedSet<ScopedEntity> elements = new TreeSet<ScopedEntity>(comparator);
for(int i = 0; i < mti.getNFunctions(); ++i){
ScopedEntity scopedEntity = mti.getNthFunction(i);
if (moduleContentProvider.getShowPrivateElements() ||
scopedEntity.getScope() != Scope.PRIVATE){
elements.add(scopedEntity);
}
}
mebt = new CALWorkspace.ModuleElementsByType(moduleName, CALUIMessages.CALWorkspace_CALElementType_Functions, elements.toArray());
children.add(mebt);
moduleSourceDefinitionToModuleElementByTypeMap_functions.put(moduleName, mebt);
}
}
else{
children.add(mebt);
}
}
{
Object mebt = moduleSourceDefinitionToModuleElementByTypeMap_typeClasses.get(moduleName);
if (mebt == null){
if (mti.getNTypeClasses() > 0){
SortedSet<ScopedEntity> elements = new TreeSet<ScopedEntity>(comparator);
for(int i = 0; i < mti.getNTypeClasses(); ++i){
ScopedEntity scopedEntity = mti.getNthTypeClass(i);
if (moduleContentProvider.getShowPrivateElements() ||
scopedEntity.getScope() != Scope.PRIVATE){
elements.add(scopedEntity);
}
}
mebt = new CALWorkspace.ModuleElementsByType(moduleName, CALUIMessages.CALWorkspace_CALElementType_TypeClasses, elements.toArray());
children.add(mebt);
moduleSourceDefinitionToModuleElementByTypeMap_typeClasses.put(moduleName, mebt);
}
}
else{
children.add(mebt);
}
}
{
Object mebt = moduleSourceDefinitionToModuleElementByTypeMap_typeConstructors.get(moduleName);
if (mebt == null){
if (mti.getNTypeConstructors() > 0){
SortedSet<ScopedEntity> elements = new TreeSet<ScopedEntity>(comparator);
for(int i = 0; i < mti.getNTypeConstructors(); ++i){
ScopedEntity scopedEntity = mti.getNthTypeConstructor(i);
if (moduleContentProvider.getShowPrivateElements() ||
scopedEntity.getScope() != Scope.PRIVATE){
elements.add(scopedEntity);
}
}
mebt = new CALWorkspace.ModuleElementsByType(moduleName, CALUIMessages.CALWorkspace_CALElementType_TypeConstructors, elements.toArray());
children.add(mebt);
moduleSourceDefinitionToModuleElementByTypeMap_typeConstructors.put(moduleName, mebt);
}
}
else{
children.add(mebt);
}
}
{
Object mebt = moduleSourceDefinitionToModuleElementByTypeMap_classInstances.get(moduleName);
if (mebt == null){
if (mti.getNClassInstances() > 0){
SortedSet<ClassInstance> elements = new TreeSet<ClassInstance>(comparator);
for(int i = 0; i < mti.getNClassInstances(); ++i){
ClassInstance classInstance = mti.getNthClassInstance(i);
if (classInstance.getInstanceStyle() == ClassInstance.InstanceStyle.EXPLICIT){
elements.add(classInstance);
}
}
if (elements.size() > 0){
mebt = new CALWorkspace.ModuleElementsByType(moduleName, CALUIMessages.CALWorkspace_CALElementType_ClassInstances, elements.toArray());
children.add(mebt);
moduleSourceDefinitionToModuleElementByTypeMap_classInstances.put(moduleName, mebt);
}
}
}
else{
children.add(mebt);
}
}
}
return children.toArray();
}
else{
SortedSet<Object> children = new TreeSet<Object>(comparator);
if (mti != null){
for(int i = 0; i < mti.getNFunctions(); ++i){
ScopedEntity scopedEntity = mti.getNthFunction(i);
if (moduleContentProvider.getShowPrivateElements() ||
scopedEntity.getScope() != Scope.PRIVATE){
children.add(scopedEntity);
}
}
for(int i = 0; i < mti.getNTypeClasses(); ++i){
ScopedEntity scopedEntity = mti.getNthTypeClass(i);
if (moduleContentProvider.getShowPrivateElements() ||
scopedEntity.getScope() != Scope.PRIVATE){
children.add(scopedEntity);
}
add(children, getChildren(scopedEntity, true));
}
for(int i = 0; i < mti.getNTypeConstructors(); ++i){
ScopedEntity scopedEntity = mti.getNthTypeConstructor(i);
if (moduleContentProvider.getShowPrivateElements() ||
scopedEntity.getScope() != Scope.PRIVATE){
children.add(scopedEntity);
}
add(children, getChildren(scopedEntity, true));
}
for(int i = 0; i < mti.getNClassInstances(); ++i){
ClassInstance classInstance = mti.getNthClassInstance(i);
if (classInstance.getInstanceStyle() == ClassInstance.InstanceStyle.EXPLICIT){
children.add(classInstance);
}
}
}
return children.toArray();
}
}
else if (parent instanceof Function){
Function function = (Function) parent;
if (function.getNLocalFunctions() > 0){
return new Object[0];
}
return new Object[0];
}
else if (
parent instanceof TypeConstructor &&
(alwaysGetChildren || this.moduleContentProvider.getShowElementHierarchy())){
TypeConstructor tc = (TypeConstructor) parent;
final int nDataConstructors = tc.getNDataConstructors();
ArrayList<DataConstructor> children = new ArrayList<DataConstructor>(nDataConstructors);
for(int i = 0; i < nDataConstructors; ++i){
if (moduleContentProvider.getShowPrivateElements() ||
tc.getNthDataConstructor(i).getScope() != Scope.PRIVATE){
children.add(tc.getNthDataConstructor(i));
}
}
return children.toArray();
}
else if (parent instanceof TypeClass &&
(alwaysGetChildren || this.moduleContentProvider.getShowElementHierarchy())){
TypeClass tc = (TypeClass) parent;
final int nClassMethods = tc.getNClassMethods();
ArrayList<ClassMethod> children = new ArrayList<ClassMethod>(nClassMethods);
for(int i = 0; i < nClassMethods; ++i){
if (moduleContentProvider.getShowPrivateElements() ||
tc.getNthClassMethod(i).getScope() != Scope.PRIVATE){
children.add(tc.getNthClassMethod(i));
}
}
return children.toArray();
}
else if (parent instanceof ModuleElementsByType){
return ((ModuleElementsByType) parent).getChildren();
}
else{
return new Object[0];
}
}
public boolean hasChildren(Object parent) {
if (parent instanceof HierarchicalNode){
return ((HierarchicalNode) parent).hasChildren();
}
else if (parent instanceof ModuleName){
ModuleName moduleName = (ModuleName) parent;
ModuleTypeInfo mti = this.moduleContentProvider.getCALModelManager().getModuleTypeInfo(moduleName);
if (mti == null){
// module has no definitions in it. This can happen.
return false;
}
return
mti.getNFunctions() > 0 ||
mti.getNTypeClasses() > 0 ||
mti.getNTypeConstructors() > 0 ||
mti.getNClassInstances() > 0;
}
else if (parent instanceof ModuleElementsByType){
return ((ModuleElementsByType) parent).hasChildren();
}
else if (parent instanceof TypeConstructor){
if (!this.moduleContentProvider.getShowElementHierarchy()){
return false;
}
TypeConstructor tc = (TypeConstructor) parent;
if (moduleContentProvider.getShowPrivateElements()){
return tc.getNDataConstructors() > 0;
}
else{
for(int i = 0; i < tc.getNDataConstructors(); ++i){
if (tc.getNthDataConstructor(i).getScope() != Scope.PRIVATE){
return true;
}
}
return false;
}
}
else if (parent instanceof TypeClass){
if (!this.moduleContentProvider.getShowElementHierarchy()){
return false;
}
TypeClass tc = (TypeClass) parent;
if (moduleContentProvider.getShowPrivateElements()){
return tc.getNClassMethods() > 0;
}
else{
for(int i = 0; i < tc.getNClassMethods(); ++i){
if (tc.getNthClassMethod(i).getScope() != Scope.PRIVATE){
return true;
}
}
return false;
}
}
else{
return false;
}
}
/**
* Remove any cached information associated with the given module.
*
* @param moduleName the name of the module that has changed.
*/
private void moduleHasChanged(ModuleName moduleName){
moduleSourceDefinitionToModuleElementByTypeMap_functions.remove(moduleName);
moduleSourceDefinitionToModuleElementByTypeMap_typeClasses.remove(moduleName);
moduleSourceDefinitionToModuleElementByTypeMap_typeConstructors.remove(moduleName);
moduleSourceDefinitionToModuleElementByTypeMap_classInstances.remove(moduleName);
}
/*
* We will set up a dummy model to initialize tree heararchy.
* In a real code, you will connect to a real model and
* expose its hierarchy.
*/
protected void initialize() {
if (this.moduleContentProvider.getShowModuleHierarchy()){
// Hierarchical modules
HierarchicalNode root = new HierarchicalNode("Invisible Root", this.root);
invisibleRoot = root;
for (final Object element : calModelManager.getModuleNames()) {
root.add((ModuleName) element);
}
}
else{
// Flat modules
invisibleRoot = calModelManager.getModuleNames();
}
moduleSourceDefinitionToModuleElementByTypeMap_functions.clear();
moduleSourceDefinitionToModuleElementByTypeMap_typeClasses.clear();
moduleSourceDefinitionToModuleElementByTypeMap_typeConstructors.clear();
moduleSourceDefinitionToModuleElementByTypeMap_classInstances.clear();
}
private void hookIntoCompiler(){
CALBuilder.addListener(new CALBuilder.BuildMessagesListener(){
public void notify(Collection<ModuleName> modulesWithErrors) {
for (final ModuleName moduleName : modulesWithErrors) {
refreshModule(moduleName, false);
}
}
});
// When the compiled modules change then update the model
calModelManager.getProgramModelManager().addStatusListener(
compileStatusListener = new StatusListener.StatusListenerAdapter() {
@Override
public void setModuleStatus(StatusListener.Status.Module moduleStatus, ModuleName moduleName) {
if (viewer != null && moduleStatus == StatusListener.SM_LOADED){
refreshModule(moduleName, false);
}
}
}
);
}
private void refreshModule(ModuleName moduleName, final boolean updateOnlyModuleName) {
try{
final ModuleSourceDefinition msd = calModelManager.getModuleSourceDefinition(moduleName);
viewer.getControl().getDisplay().asyncExec(
new Runnable(){
public void run() {
if (msd != null){ // msd is null if using an embedded editor
moduleHasChanged(msd.getModuleName());
refreshForModule (msd, updateOnlyModuleName);
calBuilderWasEnabled = true;
}
}
});
}
catch(org.eclipse.swt.SWTException ex){
/*
* For some reason if the object is not visible and a refresh is called for
* this can through a disposed error.
*/
if (ex.code == SWT.ERROR_WIDGET_DISPOSED){
// ignore
}
}
}
protected abstract void refreshForModule (ModuleSourceDefinition moduleSourceDefinition, boolean updateOnlyModule);
}