📄 csparser.cs
字号:
// CSParser.cs
// Copyright (c) 2000 Mike Krueger
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Collections;
using System.IO;
using SharpDevelop.Internal.Text;
using SharpDevelop.Internal.Project;
namespace SharpDevelop.Internal.Parser {
public class Namespace
{
string name;
long line;
public ArrayList Namespaces = new ArrayList();
public ArrayList Classes = new ArrayList();
public Namespace(string name, long line)
{
this.name = name;
this.line = line;
}
public string Name {
get {
return name;
}
}
public long Line {
get {
return line;
}
}
}
public enum MemberType { Class, Field, Property, Method };
public class MemberInfo
{
string filename;
string name;
long line;
public MemberType type;
public MemberInfo(string filename, string name, long line)
{
this.filename = filename;
this.name = name;
this.line = line;
}
public string FileName {
get {
return filename;
}
}
public string Name {
get {
return name;
}
}
public long Line {
get {
return line;
}
}
}
public class Class : MemberInfo
{
public ArrayList Members = new ArrayList();
public Class(string filename, string name, long line) : base(filename, name, line)
{
type = MemberType.Class;
}
}
public class FileInfo
{
string name;
ArrayList namespaces = new ArrayList();
public FileInfo(string name)
{
this.name = name;
namespaces.Add("");
}
public ArrayList NameSpaces {
get {
return namespaces;
}
}
public string FileName {
get {
return name;
}
}
}
public class CSParser
{
public Namespace Global;
public Hashtable FileInfos = new Hashtable();
Stack Namespaces = new Stack();
string param;
string text;
string id;
string filename;
int counter = 0;
long curLine = 0;
FileInfo curFile;
public CSParser()
{}
public void Parse(SharpDevelop.Internal.Project.ISdProject p)
{
Global = new Namespace("GLOBAL", 0);
FileInfos = new Hashtable();
foreach (string file in p.Files)
if (Path.GetExtension(file).Equals(".cs")) {
counter = 0;
curLine = 0;
curFile = new FileInfo(file);
this.filename = file;
StreamReader s = File.OpenText(file);
this.text = s.ReadToEnd();
s.Close();
Namespaces.Clear();
Namespaces.Push(Global);
Program();
FileInfos[file] = curFile;
}
}
public void Parse(TextBuffer buffer)
{
counter = 0;
curLine = 0;
Global = new Namespace("GLOBAL", 0);
// this.filename = buffer.FileName;
this.text = buffer.Text;
curFile = new FileInfo(filename);
Namespaces.Push(Global);
Program();
FileInfos[filename] = curFile;
}
void Program()
{
while (counter < text.Length)
{
SkipWhiteSpaces();
ReadClassOrNamespace();
}
}
void ReadClassMembers(Class c)
{
while (counter < text.Length && text[counter] != '{') {
if (counter < text.Length && text[counter] == '/') {
SkipDocumentation();
continue;
}
if (counter < text.Length && text[counter] == '"') {
SkipString();
continue;
}
if (counter < text.Length && text[counter] == '\n')
++curLine;
++counter;
}
++counter;
bool method = false;
while (counter < text.Length) {
if (counter < text.Length && text[counter] == '/') {
SkipDocumentation();
continue;
}
if (counter < text.Length && text[counter] == '{') {
if (!method) {
MemberInfo mi = new MemberInfo(filename, id, curLine);
mi.type = MemberType.Property; // property
c.Members.Add(mi);
}
SkipBlock();
method = false;
}
if (counter < text.Length && text[counter] == '"') {
SkipString();
continue;
}
if (counter < text.Length && text[counter] == '(') {
MemberInfo mi = new MemberInfo(filename, id, curLine);
mi.type = MemberType.Method; // method
c.Members.Add(mi);
method = true;
SkipBlock();
}
if (counter < text.Length && text[counter] == ';') {
MemberInfo mi = new MemberInfo(filename, id, curLine);
mi.type = MemberType.Field; // field
c.Members.Add(mi);
}
if (counter < text.Length && Char.IsLetter(text[counter])) {
ReadIdentifer();
}
if (counter < text.Length && text[counter] == '\n')
++curLine;
++counter;
}
++counter;
}
void ReadMembers()
{
while (counter < text.Length)
{
SkipWhiteSpaces();
if (counter + 8 < text.Length && text.Substring(counter, 8).ToUpper().Equals("PROTECTED")) {
counter += 8;
} else
if (counter + 7 < text.Length && text.Substring(counter, 7).ToUpper().Equals("PRIVATE")) {
counter += 7;
} else
if (counter + 6 < text.Length && text.Substring(counter, 6).ToUpper().Equals("PUBLIC")) {
counter += 6;
} else
if (counter + 6 < text.Length && text.Substring(counter, 6).ToUpper().Equals("STATIC")) {
counter += 6;
} else
if (counter + 5 < text.Length && text.Substring(counter, 5).ToUpper().Equals("CLASS")) {
counter += 5;
SkipWhiteSpaces();
ReadIdentifer();
ReadMembers();
} else
if (counter < text.Length) {
ReadIdentifer();
string type = id;
ReadIdentifer();
string name = id;
SkipWhiteSpaces();
if (text[counter] == '{') {
SkipBlock();
} else
if (text[counter] == '(') {
ReadParams();
} else {
}
}
}
}
void ReadClassOrNamespace()
{
SkipWhiteSpaces();
bool openbracket = text[counter] == '{';
Namespace curSpace = (Namespace)Namespaces.Peek();
while (counter < text.Length) {
SkipWhiteSpaces();
if (counter < text.Length && text[counter] == '"') {
SkipString();
continue;
}
if (counter < text.Length && openbracket && text[counter] == '}') {
SkipWhiteSpaces();
ReadIdentifer();
}
if (counter + 5 < text.Length && text.Substring(counter, 5).ToUpper().Equals("USING")) {
counter += 5;
SkipWhiteSpaces();
ReadIdentifer();
curFile.NameSpaces.Add(id);
} else
if (counter + 4 < text.Length && text.Substring(counter, 4).ToUpper().Equals("ENUM")) {
counter += 4;
SkipWhiteSpaces();
ReadIdentifer();
SkipWhiteSpaces();
SkipBlock(); // TODO : Read Enum Members
} else
if (counter + 9 < text.Length && text.Substring(counter, 9).ToUpper().Equals("INTERFACE")) {
counter += 9;
SkipWhiteSpaces();
ReadIdentifer();
curSpace.Classes.Add(new Class(filename, id, curLine));
SkipWhiteSpaces();
SkipBlock(); // TODO : Read Class Members
} else
if (counter + 6 < text.Length && text.Substring(counter, 6).ToUpper().Equals("STRUCT")) {
counter += 6;
SkipWhiteSpaces();
ReadIdentifer();
curSpace.Classes.Add(new Class(filename, id, curLine));
SkipWhiteSpaces();
SkipBlock(); // TODO : Read Class Members
} else
if (counter + 5 < text.Length && text.Substring(counter, 5).ToUpper().Equals("CLASS")) {
counter += 5;
SkipWhiteSpaces();
ReadIdentifer();
Class c = new Class(filename, id, curLine);
curSpace.Classes.Add(c);
SkipWhiteSpaces();
// ReadClassMembers(c);
SkipBlock(); // TODO : Read Class Members
} else
if (counter + 9 < text.Length && text.Substring(counter, 9).ToUpper().Equals("NAMESPACE")) {
counter += 9;
SkipWhiteSpaces();
ReadIdentifer();
Namespace newspace = null;
string[] namespacepath = id.Split(new char[] { '.' });
for (int i = 0; i < namespacepath.Length; ++i) {
Console.WriteLine(namespacepath[i]);
}
Console.WriteLine("----------");
newspace = GetNamespace(Global, 0, namespacepath);
// if (newspace == null) {
// newspace = new Namespace(id, curLine);
// curSpace.Namespaces.Add(newspace);
// }
Namespaces.Push(newspace);
ReadClassOrNamespace();
Namespaces.Pop();
} else
++counter;
}
}
Namespace GetNamespace(Namespace node, int ptr, string[] path)
{
for (int i = 0; i < node.Namespaces.Count; ++i) {
Namespace curSpace = (Namespace)node.Namespaces[i];
if (curSpace.Name.Equals(path[ptr])) {
++ptr;
if (ptr >= path.Length)
return curSpace;
return GetNamespace(curSpace, ptr, path);
}
}
node.Namespaces.Add(new Namespace(path[ptr], -1));
return GetNamespace(node, ptr, path);
}
void ReadParams()
{
SkipWhiteSpaces();
param = "";
while (counter < text.Length && text[counter] != ')') {
param += text[counter];
++counter;
}
}
void ReadIdentifer()
{
SkipWhiteSpaces();
id = "";
while (counter < text.Length && text[counter] != ';' && (Char.IsLetterOrDigit(text[counter]) || text[counter] == '_')) {
id += text[counter];
++counter;
}
}
void SkipString()
{
++counter;
while (counter < text.Length && text[counter] != '"') {
if (text[counter] == '\n')
++curLine;
++counter;
}
++counter;
}
void SkipBlock()
{
int braces = 0;
while (counter < text.Length && text[counter] != '{') {
if (counter < text.Length && text[counter] == '/') {
SkipDocumentation();
continue;
}
if (counter < text.Length && text[counter] == '"') {
SkipString();
continue;
}
if (counter < text.Length && text[counter] == '\n')
++curLine;
++counter;
}
++counter;
while (counter < text.Length) {
if (counter < text.Length && text[counter] == '/') {
SkipDocumentation();
continue;
}
if (counter < text.Length && text[counter] == '{')
++braces;
if (counter < text.Length && text[counter] == '}') {
--braces;
if (braces < 0)
break;
}
if (counter < text.Length && text[counter] == '"') {
SkipString();
continue;
}
if (counter < text.Length && text[counter] == '\n')
++curLine;
++counter;
}
++counter;
}
void SkipDocumentation()
{
++counter;
if (counter >= text.Length)
return;
if (text[counter] == '/') { // line comment
while (counter < text.Length && text[counter] != '\n')
++counter;
return;
}
if (text[counter] == '*') { // block comment
while (counter + 1 < text.Length && text[counter] != '*' && text[counter + 1] != '/') {
if (text[counter] == '\n')
++curLine;
++counter;
}
counter += 2;
return;
}
}
void SkipWhiteSpaces()
{
while (counter < text.Length && Char.IsWhiteSpace(text[counter])) {
if (text[counter] == '\n')
++curLine;
++counter;
}
if (counter < text.Length && text[counter] == '/') {
SkipDocumentation();
SkipWhiteSpaces();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -