#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

235 lines
6.7 KiB

// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.Core
{
public class ParseProjectContent : DefaultProjectContent
{
internal static ParseProjectContent CreateUninitalized(IProject project)
{
ParseProjectContent newProjectContent = new ParseProjectContent();
newProjectContent.project = project;
newProjectContent.Language = project.LanguageProperties;
newProjectContent.ReferencedContents.Add(ProjectContentRegistry.Mscorlib);
newProjectContent.initializing = true;
return newProjectContent;
}
public static ParseProjectContent Create(IProject project)
{
ParseProjectContent newProjectContent = CreateUninitalized(project);
newProjectContent.Initialize1();
newProjectContent.Initialize2();
return newProjectContent;
}
IProject project;
public override IProject Project {
get {
return project;
}
}
bool initializing;
public override string ToString()
{
return string.Format("[{0}: {1}]", GetType().Name, project.Name);
}
internal void Initialize1()
{
ProjectItem[] items = project.Items.ToArray();
ProjectService.ProjectItemAdded += OnProjectItemAdded;
ProjectService.ProjectItemRemoved += OnProjectItemRemoved;
ProjectService.EndBuild += OnEndBuild;
UpdateDefaultImports(items);
foreach (ProjectItem item in items) {
if (!initializing) return; // abort initialization
switch (item.ItemType) {
case ItemType.Reference:
case ItemType.ProjectReference:
case ItemType.COMReference:
AddReference(item as ReferenceProjectItem, false);
break;
}
}
UpdateReferenceInterDependencies();
WorkbenchSingleton.SafeThreadAsyncCall(this, "OnReferencedContentsChanged", EventArgs.Empty);
}
void UpdateReferenceInterDependencies()
{
// Use ToArray because the collection could be modified inside the loop
foreach (IProjectContent referencedContent in this.referencedContents.ToArray()) {
if (referencedContent is ReflectionProjectContent) {
((ReflectionProjectContent)referencedContent).InitializeReferences();
}
}
}
void AddReference(ReferenceProjectItem reference, bool updateInterDependencies)
{
try {
IProjectContent referencedContent = ProjectContentRegistry.GetProjectContentForReference(reference);
if (referencedContent != null) {
ReferencedContents.Add(referencedContent);
}
if (updateInterDependencies) {
UpdateReferenceInterDependencies();
}
WorkbenchSingleton.SafeThreadAsyncCall(this, "OnReferencedContentsChanged", EventArgs.Empty);
} catch (Exception e) {
MessageService.ShowError(e);
}
}
// waitcallback for AddReference
void AddReference(object state)
{
AddReference((ReferenceProjectItem)state, true);
}
void OnProjectItemAdded(object sender, ProjectItemEventArgs e)
{
if (e.Project != project) return;
ReferenceProjectItem reference = e.ProjectItem as ReferenceProjectItem;
if (reference != null) {
System.Threading.ThreadPool.QueueUserWorkItem(AddReference, reference);
}
switch (e.ProjectItem.ItemType) {
case ItemType.Import:
UpdateDefaultImports(project.Items.ToArray());
break;
case ItemType.Compile:
ParserService.EnqueueForParsing(e.ProjectItem.FileName);
break;
}
}
void OnProjectItemRemoved(object sender, ProjectItemEventArgs e)
{
if (e.Project != project) return;
ReferenceProjectItem reference = e.ProjectItem as ReferenceProjectItem;
if (reference != null) {
try {
IProjectContent referencedContent = ProjectContentRegistry.GetProjectContentForReference(reference);
if (referencedContent != null) {
ReferencedContents.Remove(referencedContent);
OnReferencedContentsChanged(EventArgs.Empty);
}
} catch (Exception ex) {
MessageService.ShowError(ex);
}
}
switch (e.ProjectItem.ItemType) {
case ItemType.Import:
UpdateDefaultImports(project.Items.ToArray());
break;
case ItemType.Compile:
ParserService.ClearParseInformation(e.ProjectItem.FileName);
break;
}
}
int languageDefaultImportCount = -1;
void UpdateDefaultImports(ProjectItem[] items)
{
if (languageDefaultImportCount < 0) {
languageDefaultImportCount = (DefaultImports != null) ? DefaultImports.Usings.Count : 0;
}
if (languageDefaultImportCount == 0) {
DefaultImports = null;
} else {
while (DefaultImports.Usings.Count > languageDefaultImportCount) {
DefaultImports.Usings.RemoveAt(languageDefaultImportCount);
}
}
foreach (ProjectItem item in items) {
if (item.ItemType == ItemType.Import) {
if (DefaultImports == null) {
DefaultImports = new DefaultUsing(this);
}
DefaultImports.Usings.Add(item.Include);
}
}
}
internal int GetInitializationWorkAmount()
{
return project.Items.Count;
}
internal void Initialize2()
{
if (!initializing) return;
int progressStart = StatusBarService.ProgressMonitor.WorkDone;
ParseableFileContentEnumerator enumerator = new ParseableFileContentEnumerator(project);
try {
StatusBarService.ProgressMonitor.TaskName = "Parsing " + project.Name + "...";
foreach (IProjectContent referencedContent in ReferencedContents) {
if (referencedContent is ReflectionProjectContent) {
((ReflectionProjectContent)referencedContent).InitializeReferences();
}
}
while (enumerator.MoveNext()) {
int i = enumerator.Index;
if ((i % 5) == 2)
StatusBarService.ProgressMonitor.WorkDone = progressStart + i;
ParserService.ParseFile(this, enumerator.CurrentFileName, enumerator.CurrentFileContent, true, false);
if (!initializing) return;
}
} finally {
initializing = false;
StatusBarService.ProgressMonitor.WorkDone = progressStart + enumerator.ItemCount;
enumerator.Dispose();
}
}
public override void Dispose()
{
ProjectService.ProjectItemAdded -= OnProjectItemAdded;
ProjectService.ProjectItemRemoved -= OnProjectItemRemoved;
ProjectService.EndBuild -= OnEndBuild;
initializing = false;
base.Dispose();
}
void OnEndBuild(object source, EventArgs e)
{
AddComReferences();
}
void AddComReferences()
{
if (project != null) {
foreach (ProjectItem item in project.Items) {
if (item.ItemType == ItemType.COMReference) {
System.Threading.ThreadPool.QueueUserWorkItem(AddReference, item as ReferenceProjectItem);
}
}
}
}
}
}