Permalink
Browse files

Refactor PythonAstWalker.

  • Loading branch information...
1 parent c0c8677 commit 4efdaf8eddaac72c8c71b65f12780d282071e15d @mrward mrward committed Sep 29, 2010
View
9 src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
@@ -93,22 +93,30 @@
<Compile Include="Src\IPythonResolver.cs" />
<Compile Include="Src\MemberName.cs" />
<Compile Include="Src\PythonBuiltInModuleMemberName.cs" />
+ <Compile Include="Src\PythonClass.cs" />
<Compile Include="Src\PythonClassResolver.cs" />
<Compile Include="Src\PythonCodeCompletionItemProvider.cs" />
+ <Compile Include="Src\PythonCompilationUnit.cs" />
<Compile Include="Src\PythonCompletionItemList.cs" />
<Compile Include="Src\PythonConsoleApplication.cs" />
+ <Compile Include="Src\PythonConstructor.cs" />
<Compile Include="Src\PythonDotNetMethodResolver.cs" />
<Compile Include="Src\PythonFromImport.cs" />
<Compile Include="Src\PythonImport.cs" />
<Compile Include="Src\PythonLanguageBinding.cs" />
<Compile Include="Src\PythonLocalVariableResolver.cs" />
<Compile Include="Src\PythonMemberResolver.cs" />
+ <Compile Include="Src\PythonMethod.cs" />
+ <Compile Include="Src\PythonMethodDefinition.cs" />
<Compile Include="Src\PythonMethodGroupResolveResult.cs" />
+ <Compile Include="Src\PythonMethodOrClassBodyRegion.cs" />
<Compile Include="Src\PythonMethodResolver.cs" />
+ <Compile Include="Src\PythonModule.cs" />
<Compile Include="Src\PythonModuleCompletionItems.cs" />
<Compile Include="Src\PythonModuleCompletionItemsFactory.cs" />
<Compile Include="Src\PythonImportResolver.cs" />
<Compile Include="Src\PythonNamespaceResolver.cs" />
+ <Compile Include="Src\PythonProperty.cs" />
<Compile Include="Src\PythonPropertyAssignment.cs" />
<Compile Include="Src\PythonResolverContext.cs" />
<Compile Include="Src\PythonSelfResolver.cs" />
@@ -125,6 +133,7 @@
<Compile Include="Src\PythonTestRunnerApplication.cs" />
<Compile Include="Src\PythonTestRunnerContext.cs" />
<Compile Include="Src\PythonTestRunnerResponseFile.cs" />
+ <Compile Include="Src\PythonUsingScope.cs" />
<Compile Include="Src\PythonWorkbench.cs" />
<Compile Include="Src\SendLineToPythonConsoleCommand.cs" />
<Compile Include="Src\SendSelectedTextToPythonConsoleCommand.cs" />
View
205 src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonAstWalker.cs
@@ -18,32 +18,16 @@ namespace ICSharpCode.PythonBinding
/// </summary>
public class PythonAstWalker : PythonWalker
{
- DefaultCompilationUnit compilationUnit;
+ PythonCompilationUnit compilationUnit;
IClass currentClass;
- IClass globalClass;
+ PythonModule module;
/// <summary>
/// All classes in a file take the namespace of the filename.
/// </summary>
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);
}
/// <summary>
@@ -62,184 +46,73 @@ public void Walk(Statement statement)
statement.Walk(this);
}
- /// <summary>
- /// Walks a class definition.
- /// </summary>
- 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;
}
- /// <summary>
- /// Walks a function definition.
- /// </summary>
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;
- }
-
- /// <summary>
- /// Walks an import statement and adds it to the compilation unit's
- /// Usings.
- /// </summary>
- 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;
}
-
- /// <summary>
- /// Gets the body region for a class or a method.
- /// </summary>
- /// <remarks>
- /// Note that SharpDevelop line numbers are zero based but the
- /// DomRegion values are one based. IronPython columns and lines are one based.
- /// </remarks>
- /// <param name="body">The body statement.</param>
- /// <param name="header">The location of the header. This gives the end location for the
- /// method or class definition up to the colon.</param>
- 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);
- }
/// <summary>
- /// 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.
/// </summary>
- /// <remarks>
- /// A class region includes the body.
- /// </remarks>
- DomRegion GetRegion(ScopeStatement statement)
+ IClass GetClassBeingWalked()
{
- return new DomRegion(statement.Start.Line, statement.Start.Column, statement.End.Line, statement.End.Column);
- }
-
- /// <summary>
- /// Gets the region of a method. This does not include the body.
- /// </summary>
- DomRegion GetMethodRegion(FunctionDefinition node)
- {
- return new DomRegion(node.Start.Line, node.Start.Column, node.Header.Line, node.Header.Column + 1);
- }
-
- /// <summary>
- /// Looks for any base types for the class defined in the
- /// list of expressions and adds them to the class.
- /// </summary>
- void AddBaseTypes(IClass c, IList<Expression> 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;
}
/// <summary>
- /// 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.
/// </summary>
- 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);
- }
-
- /// <summary>
- /// Converts from Python AST expressions to parameters.
- /// </summary>
- /// <remarks>If the parameters belong to a class method then the first
- /// "self" parameter can be ignored.</remarks>
- IParameter[] ConvertParameters(IList<Parameter> parameters, bool ignoreFirstParameter)
- {
- List<IParameter> convertedParameters = new List<IParameter>();
-
- 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();
}
/// <summary>
- /// 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.
/// </summary>
- 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;
}
- /// <summary>
- /// Creates the dummy class that is used to hold global methods.
- /// </summary>
- 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 @@ public override bool Walk(AssignmentStatement node)
void WalkPropertyAssignment(AssignmentStatement node)
{
PythonPropertyAssignment propertyAssignment = new PythonPropertyAssignment(node);
- if (propertyAssignment.IsProperty()) {
- propertyAssignment.AddPropertyToClass(currentClass);
- }
+ propertyAssignment.CreateProperty(currentClass);
}
}
}
View
91 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);
+ }
+
+ /// <summary>
+ /// Adds the namespace to the class name taken from the class definition.
+ /// </summary>
+ 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);
+ }
+
+ /// <summary>
+ /// Gets the region of the scope statement (ClassDefinition).
+ /// </summary>
+ /// <remarks>
+ /// A class region includes the body.
+ /// </remarks>
+ void GetRegion(ScopeStatement statement)
+ {
+ Region = new DomRegion(statement.Start.Line, statement.Start.Column, statement.End.Line, statement.End.Column);
+ }
+
+ /// <summary>
+ /// Looks for any base types for the class defined in the
+ /// list of expressions and adds them to the class.
+ /// </summary>
+ void AddBaseTypes(IList<Expression> 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);
+ }
+ }
+
+ /// <summary>
+ /// Adds the named base type to the class.
+ /// </summary>
+ 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);
+ }
+ }
+}
View
18 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);
+ }
+ }
+}
View
17 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")
+ {
+ }
+ }
+}
View
98 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);
+ }
+
+ /// <summary>
+ /// Gets the region of a method. This does not include the body.
+ /// </summary>
+ 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);
+ }
+ }
+
+ /// <summary>
+ /// Converts from Python AST expressions to parameters.
+ /// </summary>
+ /// <remarks>If the parameters belong to a class method then the first
+ /// "self" parameter can be ignored.</remarks>
+ IParameter[] ConvertParameters(IList<Parameter> parameters, bool ignoreFirstParameter)
+ {
+ int startingIndex = GetStartingIndex(ignoreFirstParameter);
+ return ConvertParameters(parameters, startingIndex);
+ }
+
+ int GetStartingIndex(bool ignoreFirstParameter)
+ {
+ if (ignoreFirstParameter) {
+ return 1;
+ }
+ return 0;
+ }
+
+ IParameter[] ConvertParameters(IList<Parameter> parameters, int startingIndex)
+ {
+ List<IParameter> convertedParameters = new List<IParameter>();
+ for (int i = startingIndex; i < parameters.Count; ++i) {
+ DefaultParameter parameter = new DefaultParameter(parameters[i].Name, null, new DomRegion());
+ convertedParameters.Add(parameter);
+ }
+ return convertedParameters.ToArray();
+ }
+ }
+}
View
33 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__"; }
+ }
+ }
+}
View
39 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
+ {
+ /// <summary>
+ /// Gets the body region for a class or a method.
+ /// </summary>
+ /// <remarks>
+ /// Note that SharpDevelop line numbers are zero based but the
+ /// DomRegion values are one based. IronPython columns and lines are one based.
+ /// </remarks>
+ /// <param name="body">The body statement.</param>
+ /// <param name="header">The location of the header. This gives the end location for the
+ /// method or class definition up to the colon.</param>
+ 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);
+ }
+ }
+}
View
17 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);
+ }
+ }
+}
View
26 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);
+ }
+ }
+}
View
38 src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonPropertyAssignment.cs
@@ -16,39 +16,39 @@ public PythonPropertyAssignment(AssignmentStatement assignmentStatement)
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);
}
}
}
View
18 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();
+ }
+ }
+}
View
56 ...ddIns/BackendBindings/Python/PythonBinding/Test/Parsing/PythonParserParsePropertyTests.cs
@@ -59,5 +59,61 @@ public void Parse_ClassHasPropertyCalledCount_PropertyRegion()
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);
+ }
}
}

0 comments on commit 4efdaf8

Please sign in to comment.