diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
index 6085bbc5cf..5686e7fafd 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
@@ -93,22 +93,30 @@
+
+
+
+
+
+
+
+
@@ -125,6 +133,7 @@
+
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonAstWalker.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonAstWalker.cs
index e9024e3266..fad6d2aca5 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonAstWalker.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonAstWalker.cs
@@ -18,32 +18,16 @@ namespace ICSharpCode.PythonBinding
///
public class PythonAstWalker : PythonWalker
{
- DefaultCompilationUnit compilationUnit;
+ PythonCompilationUnit compilationUnit;
IClass currentClass;
- IClass globalClass;
+ PythonModule module;
///
/// All classes in a file take the namespace of the filename.
///
public PythonAstWalker(IProjectContent projectContent, string fileName)
{
- CreateCompilationUnit(projectContent, fileName);
- }
-
- void CreateCompilationUnit(IProjectContent projectContent, string fileName)
- {
- compilationUnit = new DefaultCompilationUnit(projectContent);
- compilationUnit.FileName = fileName;
-
- CreateUsingScopeForCompilationUnit(fileName);
- }
-
- void CreateUsingScopeForCompilationUnit(string fileName)
- {
- DefaultUsingScope usingScope = new DefaultUsingScope();
- usingScope.NamespaceName = Path.GetFileNameWithoutExtension(fileName);
- usingScope.Parent = new DefaultUsingScope();
- compilationUnit.UsingScope = usingScope;
+ compilationUnit = new PythonCompilationUnit(projectContent, fileName);
}
///
@@ -62,184 +46,73 @@ namespace ICSharpCode.PythonBinding
statement.Walk(this);
}
- ///
- /// Walks a class definition.
- ///
- public override bool Walk(ClassDefinition node)
+ public override bool Walk(ClassDefinition classDefinition)
+ {
+ PythonClass c = new PythonClass(compilationUnit, classDefinition);
+ WalkClassBody(c, classDefinition.Body);
+ return false;
+ }
+
+ void WalkClassBody(IClass c, Statement classBody)
{
- DefaultClass c = new DefaultClass(compilationUnit, GetFullyQualifiedClassName(node));
- c.Region = GetRegion(node);
- c.BodyRegion = GetBodyRegion(node.Body, node.Header);
- AddBaseTypes(c, node.Bases);
-
- // Save the class.
- compilationUnit.Classes.Add(c);
-
- // Walk through all the class items.
currentClass = c;
- node.Body.Walk(this);
+ classBody.Walk(this);
currentClass = null;
-
- return false;
}
- ///
- /// Walks a function definition.
- ///
public override bool Walk(FunctionDefinition node)
{
if (node.Body == null) {
return false;
}
- bool ignoreFirstMethodParameter = true;
- IClass c = currentClass;
- if (currentClass == null) {
- // Walking a global method.
- CreateGlobalClass();
- c = globalClass;
- ignoreFirstMethodParameter = false;
- }
+ IClass c = GetClassBeingWalked();
- // Create method.
- string methodName = node.Name;
- DomRegion bodyRegion = GetBodyRegion(node.Body, node.Header);
- DomRegion region = GetMethodRegion(node);
-
- DefaultMethod method;
- if (methodName == "__init__") {
- method = new Constructor(ModifierEnum.Public, region, bodyRegion, c);
- } else {
- method = new DefaultMethod(methodName, new DefaultReturnType(c), ModifierEnum.Public, region, bodyRegion, c);
- }
- foreach (IParameter parameter in ConvertParameters(node.Parameters, ignoreFirstMethodParameter)) {
- method.Parameters.Add(parameter);
- }
- c.Methods.Add(method);
- return false;
- }
-
- ///
- /// Walks an import statement and adds it to the compilation unit's
- /// Usings.
- ///
- public override bool Walk(ImportStatement node)
- {
- PythonImport import = new PythonImport(compilationUnit.ProjectContent, node);
- compilationUnit.UsingScope.Usings.Add(import);
- return false;
- }
-
- public override bool Walk(FromImportStatement node)
- {
- PythonFromImport import = new PythonFromImport(compilationUnit.ProjectContent, node);
- compilationUnit.UsingScope.Usings.Add(import);
+ PythonMethodDefinition methodDefinition = new PythonMethodDefinition(node);
+ methodDefinition.CreateMethod(c);
return false;
}
-
- ///
- /// Gets the body region for a class or a method.
- ///
- ///
- /// Note that SharpDevelop line numbers are zero based but the
- /// DomRegion values are one based. IronPython columns and lines are one based.
- ///
- /// The body statement.
- /// The location of the header. This gives the end location for the
- /// method or class definition up to the colon.
- DomRegion GetBodyRegion(Statement body, SourceLocation header)
- {
- int columnAfterColonCharacter = header.Column + 1;
- return new DomRegion(header.Line, header.Column + 1, body.End.Line, body.End.Column);
- }
///
- /// Gets the region of the scope statement (typically a ClassDefinition).
+ /// If the current class is null then create a module so a method outside of a class can be
+ /// parsed.
///
- ///
- /// A class region includes the body.
- ///
- DomRegion GetRegion(ScopeStatement statement)
+ IClass GetClassBeingWalked()
{
- return new DomRegion(statement.Start.Line, statement.Start.Column, statement.End.Line, statement.End.Column);
- }
-
- ///
- /// Gets the region of a method. This does not include the body.
- ///
- DomRegion GetMethodRegion(FunctionDefinition node)
- {
- return new DomRegion(node.Start.Line, node.Start.Column, node.Header.Line, node.Header.Column + 1);
- }
-
- ///
- /// Looks for any base types for the class defined in the
- /// list of expressions and adds them to the class.
- ///
- void AddBaseTypes(IClass c, IList baseTypes)
- {
- foreach (Expression expression in baseTypes) {
- NameExpression nameExpression = expression as NameExpression;
- MemberExpression memberExpression = expression as MemberExpression;
- if (nameExpression != null) {
- AddBaseType(c, nameExpression.Name);
- } else if (memberExpression != null) {
- AddBaseType(c, PythonControlFieldExpression.GetMemberName(memberExpression));
- }
+ if (currentClass == null) {
+ // Walking a method outside a class.
+ CreateModule();
+ return module;
}
+ return currentClass;
}
///
- /// Adds the named base type to the class.
+ /// Creates the module which will act as a class so it can hold any methods defined in the module.
///
- void AddBaseType(IClass c, string name)
+ void CreateModule()
{
- c.BaseTypes.Add(CreateSearchClassReturnType(c, name));
- }
-
- SearchClassReturnType CreateSearchClassReturnType(IClass c, string name)
- {
- return new SearchClassReturnType(c.ProjectContent, c, 0, 0, name, 0);
- }
-
- ///
- /// Converts from Python AST expressions to parameters.
- ///
- /// If the parameters belong to a class method then the first
- /// "self" parameter can be ignored.
- IParameter[] ConvertParameters(IList parameters, bool ignoreFirstParameter)
- {
- List convertedParameters = new List();
-
- int startingIndex = 0;
- if (ignoreFirstParameter) {
- startingIndex = 1;
- }
-
- for (int i = startingIndex; i < parameters.Count; ++i) {
- DefaultParameter parameter = new DefaultParameter(parameters[i].Name, null, new DomRegion());
- convertedParameters.Add(parameter);
+ if (module == null) {
+ module = new PythonModule(compilationUnit);
}
- return convertedParameters.ToArray();
}
///
- /// Adds the namespace to the class name taken from the class definition.
+ /// Walks an import statement and adds it to the compilation unit's
+ /// Usings.
///
- string GetFullyQualifiedClassName(ClassDefinition classDef)
+ public override bool Walk(ImportStatement node)
{
- return String.Concat(compilationUnit.UsingScope.NamespaceName, ".", classDef.Name);
+ PythonImport import = new PythonImport(compilationUnit.ProjectContent, node);
+ compilationUnit.UsingScope.Usings.Add(import);
+ return false;
}
- ///
- /// Creates the dummy class that is used to hold global methods.
- ///
- void CreateGlobalClass()
+ public override bool Walk(FromImportStatement node)
{
- if (globalClass == null) {
- globalClass = new DefaultClass(compilationUnit, compilationUnit.UsingScope.NamespaceName);
- compilationUnit.Classes.Add(globalClass);
- }
+ PythonFromImport import = new PythonFromImport(compilationUnit.ProjectContent, node);
+ compilationUnit.UsingScope.Usings.Add(import);
+ return false;
}
public override bool Walk(AssignmentStatement node)
@@ -254,9 +127,7 @@ namespace ICSharpCode.PythonBinding
void WalkPropertyAssignment(AssignmentStatement node)
{
PythonPropertyAssignment propertyAssignment = new PythonPropertyAssignment(node);
- if (propertyAssignment.IsProperty()) {
- propertyAssignment.AddPropertyToClass(currentClass);
- }
+ propertyAssignment.CreateProperty(currentClass);
}
}
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonClass.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonClass.cs
new file mode 100644
index 0000000000..b3d64e5176
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonClass.cs
@@ -0,0 +1,91 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using ICSharpCode.SharpDevelop.Dom;
+using IronPython.Compiler.Ast;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonClass : DefaultClass
+ {
+ public PythonClass(ICompilationUnit compilationUnit, ClassDefinition classDefinition)
+ : base(compilationUnit, String.Empty)
+ {
+ GetFullyQualifiedName(classDefinition);
+ GetClassRegions(classDefinition);
+ AddBaseTypes(classDefinition.Bases);
+
+ compilationUnit.Classes.Add(this);
+ }
+
+ ///
+ /// Adds the namespace to the class name taken from the class definition.
+ ///
+ void GetFullyQualifiedName(ClassDefinition classDefinition)
+ {
+ string ns = CompilationUnit.UsingScope.NamespaceName;
+ FullyQualifiedName = String.Format("{0}.{1}", ns, classDefinition.Name);
+ }
+
+ void GetClassRegions(ClassDefinition classDefinition)
+ {
+ GetRegion(classDefinition);
+ BodyRegion = PythonMethodOrClassBodyRegion.GetBodyRegion(classDefinition);
+ }
+
+ ///
+ /// Gets the region of the scope statement (ClassDefinition).
+ ///
+ ///
+ /// A class region includes the body.
+ ///
+ void GetRegion(ScopeStatement statement)
+ {
+ Region = new DomRegion(statement.Start.Line, statement.Start.Column, statement.End.Line, statement.End.Column);
+ }
+
+ ///
+ /// Looks for any base types for the class defined in the
+ /// list of expressions and adds them to the class.
+ ///
+ void AddBaseTypes(IList baseTypes)
+ {
+ foreach (Expression baseTypeExpression in baseTypes) {
+ AddBaseType(baseTypeExpression);
+ }
+ }
+
+ void AddBaseType(Expression baseTypeExpression)
+ {
+ NameExpression nameExpression = baseTypeExpression as NameExpression;
+ MemberExpression memberExpression = baseTypeExpression as MemberExpression;
+ if (nameExpression != null) {
+ AddBaseType(nameExpression.Name);
+ } else if (memberExpression != null) {
+ AddBaseType(memberExpression);
+ }
+ }
+
+ ///
+ /// Adds the named base type to the class.
+ ///
+ void AddBaseType(string name)
+ {
+ IReturnType returnType = CreateSearchClassReturnType(name);
+ BaseTypes.Add(returnType);
+ }
+
+ void AddBaseType(MemberExpression memberExpression)
+ {
+ string name = PythonControlFieldExpression.GetMemberName(memberExpression);
+ AddBaseType(name);
+ }
+
+ SearchClassReturnType CreateSearchClassReturnType(string name)
+ {
+ return new SearchClassReturnType(ProjectContent, this, 0, 0, name, 0);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCompilationUnit.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCompilationUnit.cs
new file mode 100644
index 0000000000..1b99582ba3
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonCompilationUnit.cs
@@ -0,0 +1,18 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.SharpDevelop.Dom;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonCompilationUnit : DefaultCompilationUnit
+ {
+ public PythonCompilationUnit(IProjectContent projectContent, string fileName)
+ : base(projectContent)
+ {
+ this.FileName = fileName;
+ this.UsingScope = new PythonUsingScope(fileName);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonConstructor.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonConstructor.cs
new file mode 100644
index 0000000000..3b4c8eef17
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonConstructor.cs
@@ -0,0 +1,17 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.SharpDevelop.Dom;
+using IronPython.Compiler.Ast;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonConstructor : PythonMethod
+ {
+ public PythonConstructor(IClass declaringType, FunctionDefinition methodDefinition)
+ : base(declaringType, methodDefinition, "#ctor")
+ {
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMethod.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMethod.cs
new file mode 100644
index 0000000000..1f9610ae84
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMethod.cs
@@ -0,0 +1,98 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using ICSharpCode.SharpDevelop.Dom;
+using IronPython.Compiler.Ast;
+using Microsoft.Scripting;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonMethod : DefaultMethod
+ {
+ public PythonMethod(IClass declaringType, FunctionDefinition methodDefinition)
+ : this(declaringType, methodDefinition, methodDefinition.Name)
+ {
+ }
+
+ public PythonMethod(IClass declaringType, FunctionDefinition methodDefinition, string name)
+ : base(declaringType, name)
+ {
+ ReturnType = new DefaultReturnType(declaringType);
+ Modifiers = ModifierEnum.Public;
+
+ GetMethodRegions(methodDefinition);
+ AddParameters(methodDefinition);
+
+ declaringType.Methods.Add(this);
+ }
+
+ void GetMethodRegions(FunctionDefinition methodDefinition)
+ {
+ GetBodyRegion(methodDefinition);
+ GetMethodRegion(methodDefinition);
+ }
+
+ void GetBodyRegion(FunctionDefinition methodDefinition)
+ {
+ BodyRegion = PythonMethodOrClassBodyRegion.GetBodyRegion(methodDefinition);
+ }
+
+ ///
+ /// Gets the region of a method. This does not include the body.
+ ///
+ void GetMethodRegion(FunctionDefinition methodDefinition)
+ {
+ SourceLocation start = methodDefinition.Start;
+ SourceLocation end = methodDefinition.Header;
+ Region = new DomRegion(start.Line, start.Column, end.Line, end.Column + 1);
+ }
+
+ void AddParameters(FunctionDefinition methodDefinition)
+ {
+ bool ignoreFirstMethodParameter = !DeclaringTypeIsPythonModule;
+ AddParameters(methodDefinition, ignoreFirstMethodParameter);
+ }
+
+ bool DeclaringTypeIsPythonModule {
+ get { return DeclaringType is PythonModule; }
+ }
+
+ void AddParameters(FunctionDefinition methodDefinition, bool ignoreFirstMethodParameter)
+ {
+ foreach (IParameter parameter in ConvertParameters(methodDefinition.Parameters, ignoreFirstMethodParameter)) {
+ Parameters.Add(parameter);
+ }
+ }
+
+ ///
+ /// Converts from Python AST expressions to parameters.
+ ///
+ /// If the parameters belong to a class method then the first
+ /// "self" parameter can be ignored.
+ IParameter[] ConvertParameters(IList parameters, bool ignoreFirstParameter)
+ {
+ int startingIndex = GetStartingIndex(ignoreFirstParameter);
+ return ConvertParameters(parameters, startingIndex);
+ }
+
+ int GetStartingIndex(bool ignoreFirstParameter)
+ {
+ if (ignoreFirstParameter) {
+ return 1;
+ }
+ return 0;
+ }
+
+ IParameter[] ConvertParameters(IList parameters, int startingIndex)
+ {
+ List convertedParameters = new List();
+ for (int i = startingIndex; i < parameters.Count; ++i) {
+ DefaultParameter parameter = new DefaultParameter(parameters[i].Name, null, new DomRegion());
+ convertedParameters.Add(parameter);
+ }
+ return convertedParameters.ToArray();
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMethodDefinition.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMethodDefinition.cs
new file mode 100644
index 0000000000..cbcd188ca7
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMethodDefinition.cs
@@ -0,0 +1,33 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.Collections.Generic;
+using ICSharpCode.SharpDevelop.Dom;
+using IronPython.Compiler.Ast;
+using Microsoft.Scripting;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonMethodDefinition
+ {
+ FunctionDefinition methodDefinition;
+
+ public PythonMethodDefinition(FunctionDefinition methodDefinition)
+ {
+ this.methodDefinition = methodDefinition;
+ }
+
+ public PythonMethod CreateMethod(IClass c)
+ {
+ if (IsConstructor) {
+ return new PythonConstructor(c, methodDefinition);
+ }
+ return new PythonMethod(c, methodDefinition);
+ }
+
+ bool IsConstructor {
+ get { return methodDefinition.Name == "__init__"; }
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMethodOrClassBodyRegion.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMethodOrClassBodyRegion.cs
new file mode 100644
index 0000000000..1c5acbc67d
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonMethodOrClassBodyRegion.cs
@@ -0,0 +1,39 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.SharpDevelop.Dom;
+using IronPython.Compiler.Ast;
+using Microsoft.Scripting;
+
+namespace ICSharpCode.PythonBinding
+{
+ public static class PythonMethodOrClassBodyRegion
+ {
+ ///
+ /// Gets the body region for a class or a method.
+ ///
+ ///
+ /// Note that SharpDevelop line numbers are zero based but the
+ /// DomRegion values are one based. IronPython columns and lines are one based.
+ ///
+ /// The body statement.
+ /// The location of the header. This gives the end location for the
+ /// method or class definition up to the colon.
+ public static DomRegion GetBodyRegion(Statement body, SourceLocation header)
+ {
+ int columnAfterColonCharacter = header.Column + 1;
+ return new DomRegion(header.Line, header.Column + 1, body.End.Line, body.End.Column);
+ }
+
+ public static DomRegion GetBodyRegion(FunctionDefinition methodDefinition)
+ {
+ return GetBodyRegion(methodDefinition.Body, methodDefinition.Header);
+ }
+
+ public static DomRegion GetBodyRegion(ClassDefinition classDefinition)
+ {
+ return GetBodyRegion(classDefinition.Body, classDefinition.Header);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonModule.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonModule.cs
new file mode 100644
index 0000000000..03d63f22bf
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonModule.cs
@@ -0,0 +1,17 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.SharpDevelop.Dom;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonModule : DefaultClass
+ {
+ public PythonModule(ICompilationUnit compilationUnit)
+ : base(compilationUnit, compilationUnit.UsingScope.NamespaceName)
+ {
+ compilationUnit.Classes.Add(this);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonProperty.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonProperty.cs
new file mode 100644
index 0000000000..324043a354
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonProperty.cs
@@ -0,0 +1,26 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using ICSharpCode.SharpDevelop.Dom;
+using Microsoft.Scripting;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonProperty : DefaultProperty
+ {
+ public PythonProperty(IClass declaringType, string name, SourceLocation location)
+ : base(declaringType, name)
+ {
+ GetPropertyRegion(location);
+ declaringType.Properties.Add(this);
+ }
+
+ void GetPropertyRegion(SourceLocation location)
+ {
+ int line = location.Line;
+ int column = location.Column;
+ Region = new DomRegion(line, column, line, column);
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyAssignment.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyAssignment.cs
index 2dba9e1534..6a0cf95f1b 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyAssignment.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyAssignment.cs
@@ -16,39 +16,39 @@ namespace ICSharpCode.PythonBinding
this.assignmentStatement = assignmentStatement;
}
- public bool IsProperty()
+ public PythonProperty CreateProperty(IClass c)
{
- CallExpression rhs = assignmentStatement.Right as CallExpression;
- if (rhs != null) {
- NameExpression nameExpression = rhs.Target as NameExpression;
+ if (IsProperty()) {
+ NameExpression nameExpression = assignmentStatement.Left[0] as NameExpression;
if (nameExpression != null) {
- return nameExpression.Name == "property";
+ string propertyName = nameExpression.Name;
+ return CreateProperty(c, propertyName);
}
}
- return false;
+ return null;
}
- public void AddPropertyToClass(IClass c)
+ bool IsProperty()
{
- NameExpression nameExpression = assignmentStatement.Left[0] as NameExpression;
- if (nameExpression != null) {
- string propertyName = nameExpression.Name;
- AddPropertyToClass(c, propertyName);
+ CallExpression callExpression = assignmentStatement.Right as CallExpression;
+ if (callExpression != null) {
+ return IsPropertyFunctionBeingCalled(callExpression);
}
+ return false;
}
- void AddPropertyToClass(IClass c, string propertyName)
+ bool IsPropertyFunctionBeingCalled(CallExpression callExpression)
{
- DefaultProperty property = new DefaultProperty(c, propertyName);
- property.Region = GetPropertyRegion();
- c.Properties.Add(property);
+ NameExpression nameExpression = callExpression.Target as NameExpression;
+ if (nameExpression != null) {
+ return nameExpression.Name == "property";
+ }
+ return false;
}
- DomRegion GetPropertyRegion()
+ PythonProperty CreateProperty(IClass c, string propertyName)
{
- int line = assignmentStatement.Start.Line;
- int column = assignmentStatement.Start.Column;
- return new DomRegion(line, column, line, column);
+ return new PythonProperty(c, propertyName, assignmentStatement.Start);
}
}
}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonUsingScope.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonUsingScope.cs
new file mode 100644
index 0000000000..4a68f3e806
--- /dev/null
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonUsingScope.cs
@@ -0,0 +1,18 @@
+// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
+// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
+
+using System;
+using System.IO;
+using ICSharpCode.SharpDevelop.Dom;
+
+namespace ICSharpCode.PythonBinding
+{
+ public class PythonUsingScope : DefaultUsingScope
+ {
+ public PythonUsingScope(string fileName)
+ {
+ NamespaceName = Path.GetFileNameWithoutExtension(fileName);
+ Parent = new DefaultUsingScope();
+ }
+ }
+}
diff --git a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Parsing/PythonParserParsePropertyTests.cs b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Parsing/PythonParserParsePropertyTests.cs
index 7586707476..f5a2a16bbf 100644
--- a/src/AddIns/BackendBindings/Python/PythonBinding/Test/Parsing/PythonParserParsePropertyTests.cs
+++ b/src/AddIns/BackendBindings/Python/PythonBinding/Test/Parsing/PythonParserParsePropertyTests.cs
@@ -59,5 +59,61 @@ namespace PythonBinding.Tests.Parsing
Assert.AreEqual(expectedRegion, region);
}
+
+ [Test]
+ public void Parse_ClassMethodHasNoPropertyButHasAssignmentStatementSetToValueFromFunctionCall_ParseInfoHasNoPropertyAdded()
+ {
+ string code =
+ "class MyClass:\r\n" +
+ " a = foo()\r\n" +
+ "\r\n";
+
+ ParseInformation parseInfo = PythonParserHelper.CreateParseInfo(code);
+ int count = parseInfo.CompilationUnit.Classes[0].Properties.Count;
+
+ Assert.AreEqual(0, count);
+ }
+
+ [Test]
+ public void Parse_ClassMethodHasNoPropertyButHasAssignmentStatementUsingMemberExpression_ParseInfoHasNoPropertyAddedAndNoExceptionThrown()
+ {
+ string code =
+ "class MyClass:\r\n" +
+ " a.b = foo()\r\n" +
+ "\r\n";
+
+ ParseInformation parseInfo = PythonParserHelper.CreateParseInfo(code);
+ int count = parseInfo.CompilationUnit.Classes[0].Properties.Count;
+
+ Assert.AreEqual(0, count);
+ }
+
+ [Test]
+ public void Parse_ClassMethodHasNoPropertyButHasAssignmentStatementSetToIntegerValue_ParseInfoHasNoPropertyAddedAndNoExceptionThrown()
+ {
+ string code =
+ "class MyClass:\r\n" +
+ " a = 1\r\n" +
+ "\r\n";
+
+ ParseInformation parseInfo = PythonParserHelper.CreateParseInfo(code);
+ int count = parseInfo.CompilationUnit.Classes[0].Properties.Count;
+
+ Assert.AreEqual(0, count);
+ }
+
+ [Test]
+ public void Parse_ClassMethodHasNoPropertyButHasAssignmentStatementSetToValueFromMemberExpressionCall_ParseInfoHasNoPropertyAddedAndNoExceptionThrown()
+ {
+ string code =
+ "class MyClass:\r\n" +
+ " a = foo.bar()\r\n" +
+ "\r\n";
+
+ ParseInformation parseInfo = PythonParserHelper.CreateParseInfo(code);
+ int count = parseInfo.CompilationUnit.Classes[0].Properties.Count;
+
+ Assert.AreEqual(0, count);
+ }
}
}
\ No newline at end of file