Wednesday, November 10, 2010

SharpDevelop :- ParserService

While working on SharpDevelop  , I got in situation where I have to construct the assembly name at runtime just before the build happens and set it as the assembly name of the SharpDevelop project.  Assembly name has to be in format  {NameSpace.ClassName.dll} . To construct this assembly name I have to parse the code file for example say MyClass.cs and get the namespace name and class name .

Previously I have done this in Visual Studio using  CodeDom (FileCodeModel, CodeElements etc).

In SharpDevelop to get the job done I followed the below algorithm :---

i)  Get the instance of currently opened project ( IProject ) . We can get it through ProjectService class     (ProjectService.CurrentProject) .

ii) Iterate the project items and find the code file/project item  to parse.

iii) Get the file path of this project item ( projectitem.FileName ) and create the instance of FileName class by calling   FileName.Create(<file path>).

iv) Create the instance of class ParsableFileContentFinder and call method Create on instance taking FileName instance as parameter (parsableContentFinderObject.Create(<FileName filename>)).This call on method parses the code file and buffers the content. This content is made available through the return type of Create method (ITextBuffer).

v) Call the ParserService.Parse(<filepath>, <ITextBuffer> ) method that takes the filepath and ITextBuffer as parameter. This method returns the ParseFileInformation object , that contains all the information related to the code elements .

Developed code on basis of above algorithm :
    
    public static void ParseNCreateWaspAssembly(string filename, out string assemblyName)  {

            assemblyName = string.Empty;
            IProject project = null;
            IEnumerable<ProjectItem> projectItems = null;
            ParseableFileContentFinder parseableFinder = null;
            string filepath = string.Empty;
            ITextBuffer contentBufferContainer = null;
            FileName targetCodefile = null;
            ParseInformation parseInfo = null;
            string projectName = string.Empty;
            string className = string.Empty;
            string nameSpace = string.Empty;

                project = ProjectService.CurrentProject;
                parseableFinder = new ParseableFileContentFinder();
                if (project != null){
                    projectItems = project.Items.AsEnumerable();
                    foreach (ProjectItem projItem in projectItems){
                        if (string.Compare(Path.GetFileNameWithoutExtension(projItem.FileName), filename,

StringComparison.OrdinalIgnoreCase) == 0){

                            filepath = projItem.FileName;
                            targetCodefile = FileName.Create(filepath);
                            if(ParserService.GetParser(filepath) != null){
                                contentBufferContainer = parseableFinder.Create(targetCodefile);
                                if(contentBufferContainer != null){
                                    parseInfo = ParserService.ParseFile(targetCodefile, contentBufferContainer);
                                    if(parseInfo != null){
                                        if (parseInfo.CompilationUnit.Classes.Count() > 0){
                                            assemblyName = parseInfo.CompilationUnit.Classes[0].FullyQualifiedName;
                                            project.AssemblyName = assemblyName;
                                            project.Save();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
        } 

That’s how we can search for the code file and get access to all the code elements .

No comments:

Post a Comment