@ -22,23 +22,67 @@ using ICSharpCode.SharpDevelop.Dom;
namespace ICSharpCode.Core
namespace ICSharpCode.Core
{
{
public class CaseSensitive ProjectContent : IProjectContent
public class Default ProjectContent : IProjectContent
{
{
List < IProjectContent > referencedContents = new List < IProjectContent > ( ) ;
List < IProjectContent > referencedContents = new List < IProjectContent > ( ) ;
Dictionary < string , IClass > classes = new Dictionary < string , IClass > ( ) ;
List < Dictionary < string , IClass > > classLists = new List < Dictionary < string , IClass > > ( ) ;
Hashtable namespaces = new Hashtable ( ) ;
Hashtable namespaces = new Hashtable ( ) ;
XmlDoc xmlDoc = new XmlDoc ( ) ;
XmlDoc xmlDoc = new XmlDoc ( ) ;
public List < Dictionary < string , IClass > > ClassLists {
get {
if ( classLists . Count = = 0 ) {
classLists . Add ( new Dictionary < string , IClass > ( language . NameComparer ) ) ;
}
return classLists ;
}
}
Dictionary < string , IClass > GetClasses ( LanguageProperties language )
{
for ( int i = 0 ; i < classLists . Count ; + + i ) {
if ( classLists [ i ] . Comparer = = language . NameComparer )
return classLists [ i ] ;
}
Dictionary < string , IClass > d ;
if ( classLists . Count > 0 ) {
Dictionary < string , IClass > oldList = classLists [ 0 ] ;
d = new Dictionary < string , IClass > ( oldList . Count , language . NameComparer ) ;
foreach ( KeyValuePair < string , IClass > pair in oldList ) {
d . Add ( pair . Key , pair . Value ) ;
}
} else {
d = new Dictionary < string , IClass > ( language . NameComparer ) ;
}
classLists . Add ( d ) ;
return d ;
}
public XmlDoc XmlDoc {
public XmlDoc XmlDoc {
get {
get {
return xmlDoc ;
return xmlDoc ;
}
}
}
}
public ICollection < IClass > Classes {
public ICollection < IClass > Classes {
get {
get {
return classes . Values ;
return ClassLists [ 0 ] . Values ;
}
}
LanguageProperties language = LanguageProperties . CSharp ;
/// <summary>
/// Gets the properties of the language this project content was written in.
/// </summary>
public LanguageProperties Language {
get {
return language ;
}
set {
if ( value = = null ) throw new ArgumentNullException ( ) ;
language = value ;
}
}
}
}
@ -70,13 +114,13 @@ namespace ICSharpCode.Core
public static IProjectContent Create ( Assembly assembly )
public static IProjectContent Create ( Assembly assembly )
{
{
CaseSensitive ProjectContent newProjectContent = new CaseSensitive ProjectContent( ) ;
Default ProjectContent newProjectContent = new Default ProjectContent( ) ;
ICompilationUnit assemblyCompilationUnit = new DefaultCompilationUnit ( newProjectContent ) ;
ICompilationUnit assemblyCompilationUnit = new DefaultCompilationUnit ( newProjectContent ) ;
foreach ( Type type in assembly . GetTypes ( ) ) {
foreach ( Type type in assembly . GetTypes ( ) ) {
if ( ! type . FullName . StartsWith ( "<" ) & & type . IsPublic ) {
if ( ! type . FullName . StartsWith ( "<" ) & & type . IsPublic ) {
newProjectContent . AddClassToNamespaceList ( new ReflectionClass ( assemblyCompilationUnit , type , null ) ) ;
newProjectContent . AddClassToNamespaceListInternal ( new ReflectionClass ( assemblyCompilationUnit , type , null ) ) ;
}
}
}
}
string fileName = LookupLocalizedXmlDoc ( assembly . Location ) ;
string fileName = LookupLocalizedXmlDoc ( assembly . Location ) ;
@ -93,44 +137,78 @@ namespace ICSharpCode.Core
return newProjectContent ;
return newProjectContent ;
}
}
public static IProjectContent Create ( IProject project )
internal static IProjectContent CreateUninitalized ( IProject project )
{
{
CaseSensitiveProjectContent newProjectContent = new CaseSensitiveProjectContent ( ) ;
DefaultProjectContent newProjectContent = new DefaultProjectContent ( ) ;
newProjectContent . project = project ;
newProjectContent . language = project . LanguageProperties ;
newProjectContent . referencedContents . Add ( ProjectContentRegistry . GetMscorlibContent ( ) ) ;
newProjectContent . referencedContents . Add ( ProjectContentRegistry . GetMscorlibContent ( ) ) ;
return newProjectContent ;
}
public static IProjectContent Create ( IProject project )
{
IProjectContent newProjectContent = CreateUninitalized ( project ) ;
if ( newProjectContent is DefaultProjectContent ) {
( ( DefaultProjectContent ) newProjectContent ) . Initialize1 ( ) ;
( ( DefaultProjectContent ) newProjectContent ) . Initialize2 ( ) ;
}
return newProjectContent ;
}
IProject project ;
// project is only used for initialization, the field is set to null after
// initialization has completed.
internal void Initialize1 ( )
{
foreach ( ProjectItem item in project . Items . ToArray ( ) ) {
foreach ( ProjectItem item in project . Items . ToArray ( ) ) {
switch ( item . ItemType ) {
switch ( item . ItemType ) {
case ItemType . Reference :
case ItemType . Reference :
case ItemType . ProjectReference :
case ItemType . ProjectReference :
IProjectContent referencedContent = ProjectContentRegistry . GetProjectContentForReference ( item as ReferenceProjectItem ) ;
IProjectContent referencedContent = ProjectContentRegistry . GetProjectContentForReference ( item as ReferenceProjectItem ) ;
if ( referencedContent ! = null ) {
if ( referencedContent ! = null ) {
newProjectContent . referencedContents . Add ( referencedContent ) ;
referencedContents . Add ( referencedContent ) ;
}
break ;
case ItemType . Compile :
ParseInformation parseInfo = ParserService . ParseFile ( item . FileName , null , true , false ) ;
if ( parseInfo ! = null ) {
newProjectContent . UpdateCompilationUnit ( null , parseInfo . BestCompilationUnit as ICompilationUnit , item . FileName , true ) ;
}
}
break ;
break ;
}
}
}
}
}
return newProjectContent ;
internal void Initialize2 ( )
{
foreach ( ProjectItem item in project . Items . ToArray ( ) ) {
if ( item . ItemType = = ItemType . Compile ) {
ParseInformation parseInfo = ParserService . ParseFile ( item . FileName , null , true , false ) ;
if ( parseInfo ! = null ) {
UpdateCompilationUnit ( null , parseInfo . BestCompilationUnit as ICompilationUnit , item . FileName , true ) ;
}
}
}
project = null ;
}
}
public Hashtable AddClassToNamespaceList ( IClass addClass )
public Hashtable AddClassToNamespaceList ( IClass addClass )
{
{
classes [ addClass . FullyQualifiedName ] = addClass ;
lock ( namespaces ) {
return AddClassToNamespaceListInternal ( addClass ) ;
}
}
Hashtable AddClassToNamespaceListInternal ( IClass addClass )
{
foreach ( Dictionary < string , IClass > classes in ClassLists ) {
classes [ addClass . FullyQualifiedName ] = addClass ;
}
string nSpace = addClass . Namespace ;
string nSpace = addClass . Namespace ;
if ( nSpace = = null ) {
if ( nSpace = = null ) {
nSpace = String . Empty ;
nSpace = String . Empty ;
}
}
string [ ] path = nSpace . Split ( '.' ) ;
Hashtable cur = namespaces ;
lock ( namespaces ) {
if ( nSpace . Length > 0 ) {
Hashtable cur = namespaces ;
string [ ] path = nSpace . Split ( '.' ) ;
for ( int i = 0 ; i < path . Length ; + + i ) {
for ( int i = 0 ; i < path . Length ; + + i ) {
object curPath = cur [ path [ i ] ] ;
object curPath = cur [ path [ i ] ] ;
if ( curPath = = null ) {
if ( curPath = = null ) {
@ -143,12 +221,12 @@ namespace ICSharpCode.Core
}
}
cur = ( Hashtable ) curPath ;
cur = ( Hashtable ) curPath ;
}
}
string name = addClass . Name = = null ? "" : addClass . Name ;
cur [ name ] = addClass ;
return cur ;
}
}
string name = addClass . Name = = null ? "" : addClass . Name ;
cur [ name ] = addClass ;
return cur ;
}
}
public void UpdateCompilationUnit ( ICompilationUnit oldUnit , ICompilationUnit parserOutput , string fileName , bool updateCommentTags )
public void UpdateCompilationUnit ( ICompilationUnit oldUnit , ICompilationUnit parserOutput , string fileName , bool updateCommentTags )
@ -158,53 +236,66 @@ namespace ICSharpCode.Core
TaskService . UpdateCommentTags ( fileName , parserOutput . TagComments ) ;
TaskService . UpdateCommentTags ( fileName , parserOutput . TagComments ) ;
}
}
if ( oldUnit ! = null ) {
lock ( namespaces ) {
RemoveClasses ( oldUnit ) ;
if ( oldUnit ! = null ) {
}
RemoveClasses ( oldUnit ) ;
}
ICompilationUnit cu = ( ICompilationUnit ) parserOutput ;
foreach ( IClass c in cu . Classes ) {
ICompilationUnit cu = ( ICompilationUnit ) parserOutput ;
AddClassToNamespaceList ( c ) ;
foreach ( IClass c in cu . Classes ) {
AddClassToNamespaceListInternal ( c ) ;
}
}
}
}
}
void RemoveClasses ( ICompilationUnit cu )
void RemoveClasses ( ICompilationUnit cu )
{
{
if ( cu ! = null ) {
if ( cu ! = null ) {
lock ( c lasses) {
foreach ( IClass c in cu . C lasses) {
foreach ( IClass c in cu . Classe s) {
foreach ( Dictionary < string , IClass > classes in ClassList s) {
classes . Remove ( c . FullyQualifiedName ) ;
classes . Remove ( c . FullyQualifiedName ) ;
}
}
}
}
// TODO: remove classes from namespace lists
}
}
}
}
#region Default Parser Layer dependent functions
#region Default Parser Layer dependent functions
public IClass GetClass ( string typeName )
public IClass GetClass ( string typeName )
{
{
return GetClass ( typeName , language , true ) ;
}
public IClass GetClass ( string typeName , LanguageProperties language , bool lookInReferences )
{
// Console.WriteLine("GetClass({0}) is known:{1}", typeName, classes.ContainsKey(typeName));
// Console.WriteLine("GetClass({0}) is known:{1}", typeName, classes.ContainsKey(typeName));
Dictionary < string , IClass > classes = GetClasses ( language ) ;
if ( classes . ContainsKey ( typeName ) ) {
if ( classes . ContainsKey ( typeName ) ) {
return classes [ typeName ] ;
return classes [ typeName ] ;
}
}
// Search in references:
// Search in references:
foreach ( IProjectContent content in referencedContents ) {
if ( lookInReferences ) {
IClass classFromContent = content . GetClass ( typeName ) ;
foreach ( IProjectContent content in referencedContents ) {
if ( classFromContent ! = null ) {
IClass classFromContent = content . GetClass ( typeName , language , false ) ;
return classFromContent ;
if ( classFromContent ! = null ) {
return classFromContent ;
}
}
}
}
}
// not found -> maybe nested type -> trying to find class that contains this one.
// not found -> maybe nested type -> trying to find class that contains this one.
int lastIndex = typeName . LastIndexOf ( '.' ) ;
int lastIndex = typeName . LastIndexOf ( '.' ) ;
if ( lastIndex > 0 ) {
if ( lastIndex > 0 ) {
string innerName = typeName . Substring ( lastIndex + 1 ) ;
string outerName = typeName . Substring ( 0 , lastIndex ) ;
string outerName = typeName . Substring ( 0 , lastIndex ) ;
IClass upperClass = GetClass ( outerName ) ;
if ( classes . ContainsKey ( outerName ) ) {
if ( upperClass ! = null & & upperClass . InnerClasses ! = null ) {
IClass upperClass = classes [ outerName ] ;
foreach ( IClass c in upperClass . InnerClasses ) {
if ( upperClass . InnerClasses ! = null ) {
if ( c . Name = = innerName ) {
string innerName = typeName . Substring ( lastIndex + 1 ) ;
return c ;
foreach ( IClass c in upperClass . InnerClasses ) {
if ( language . NameComparer . Equals ( c . Name , innerName ) ) {
return c ;
}
}
}
}
}
}
}
@ -215,18 +306,19 @@ namespace ICSharpCode.Core
public ArrayList GetNamespaceContents ( string subNameSpace )
public ArrayList GetNamespaceContents ( string subNameSpace )
{
{
ArrayList namespaceList = new ArrayList ( ) ;
ArrayList namespaceList = new ArrayList ( ) ;
AddNamespaceContents ( namespaceList , subNameSpace , language , true ) ;
return namespaceList ;
}
public void AddNamespaceContents ( ArrayList list , string subNameSpace , LanguageProperties language , bool lookInReferences )
{
if ( subNameSpace = = null ) {
if ( subNameSpace = = null ) {
return namespaceList ;
return ;
}
}
foreach ( IProjectContent content in referencedContents ) {
if ( lookInReferences ) {
foreach ( object o in content . GetNamespaceContents ( subNameSpace ) ) {
foreach ( IProjectContent content in referencedContents ) {
if ( o is string ) {
content . AddNamespaceContents ( list , subNameSpace , language , false ) ;
if ( ! namespaceList . Contains ( o ) )
namespaceList . Add ( o ) ;
} else {
namespaceList . Add ( o ) ;
}
}
}
}
}
@ -237,7 +329,7 @@ namespace ICSharpCode.Core
for ( int i = 0 ; i < path . Length ; + + i ) {
for ( int i = 0 ; i < path . Length ; + + i ) {
if ( ! ( cur [ path [ i ] ] is Hashtable ) ) {
if ( ! ( cur [ path [ i ] ] is Hashtable ) ) {
// namespace does not exist in this project content
// namespace does not exist in this project content
return namespaceList ;
return ;
}
}
cur = ( Hashtable ) cur [ path [ i ] ] ;
cur = ( Hashtable ) cur [ path [ i ] ] ;
}
}
@ -245,26 +337,31 @@ namespace ICSharpCode.Core
foreach ( DictionaryEntry entry in cur ) {
foreach ( DictionaryEntry entry in cur ) {
if ( entry . Value is Hashtable ) {
if ( entry . Value is Hashtable ) {
if ( ! namespaceL ist. Contains ( entry . Key ) )
if ( ! l ist. Contains ( entry . Key ) )
namespaceL ist. Add ( entry . Key ) ;
l ist. Add ( entry . Key ) ;
} else {
} else {
namespaceList . Add ( entry . Value ) ;
if ( ! list . Contains ( entry . Value ) )
list . Add ( entry . Value ) ;
}
}
}
}
return namespaceList ;
}
}
public bool NamespaceExists ( string name )
public bool NamespaceExists ( string name )
{
{
// Console.WriteLine("NamespaceExists({0}) == ", name);
return NamespaceExists ( name , language , true ) ;
}
public bool NamespaceExists ( string name , LanguageProperties language , bool lookInReferences )
{
if ( name = = null ) {
if ( name = = null ) {
return false ;
return false ;
}
}
foreach ( IProjectContent content in referencedContents ) {
if ( lookInReferences ) {
if ( content . NamespaceExists ( name ) ) {
foreach ( IProjectContent content in referencedContents ) {
return true ;
if ( content . NamespaceExists ( name , language , false ) ) {
return true ;
}
}
}
}
}