From d913474b6532974939d2e8c2bc8e6120db817898 Mon Sep 17 00:00:00 2001 From: Cameron Trando Date: Tue, 20 Aug 2019 10:47:51 -0700 Subject: [PATCH] Adding extension method for dunder new and init --- .../Ast/Impl/Analyzer/Symbols/FunctionEvaluator.cs | 8 +++----- .../Impl/Extensions/FunctionDefinitionExtensions.cs | 13 +++++++++++++ .../Ast/Impl/Extensions/PythonTypeExtensions.cs | 3 --- 3 files changed, 16 insertions(+), 8 deletions(-) create mode 100644 src/Analysis/Ast/Impl/Extensions/FunctionDefinitionExtensions.cs diff --git a/src/Analysis/Ast/Impl/Analyzer/Symbols/FunctionEvaluator.cs b/src/Analysis/Ast/Impl/Analyzer/Symbols/FunctionEvaluator.cs index 342ffcfd2..c323d7786 100644 --- a/src/Analysis/Ast/Impl/Analyzer/Symbols/FunctionEvaluator.cs +++ b/src/Analysis/Ast/Impl/Analyzer/Symbols/FunctionEvaluator.cs @@ -60,7 +60,7 @@ public override void Evaluate() { // Do process body of constructors since they may be declaring // variables that are later used to determine return type of other // methods and properties. - var ctor = _function.Name.EqualsOrdinal("__init__") || _function.Name.EqualsOrdinal("__new__"); + var ctor = _function.IsDunderInit() || _function.IsDunderNew(); if (ctor || returnType.IsUnknown() || Module.ModuleType == ModuleType.User) { // Return type from the annotation is sufficient for libraries and stubs, no need to walk the body. FunctionDefinition.Body?.Walk(this); @@ -119,10 +119,8 @@ public override bool Walk(ReturnStatement node) { var value = Eval.GetValueFromExpression(node.Expression); if (value != null) { // although technically legal, __init__ in a constructor should not have a not-none return value - if (FunctionDefinition.Name.EqualsOrdinal("__init__") && _function.DeclaringType.MemberType == PythonMemberType.Class - && !value.IsOfType(BuiltinTypeId.NoneType)) { - - Eval.ReportDiagnostics(Module.Uri, new Diagnostics.DiagnosticsEntry( + if (_function.IsDunderInit() && !value.IsOfType(BuiltinTypeId.NoneType)) { + Eval.ReportDiagnostics(Module.Uri, new DiagnosticsEntry( Resources.ReturnInInit, node.GetLocation(Eval).Span, ErrorCodes.ReturnInInit, diff --git a/src/Analysis/Ast/Impl/Extensions/FunctionDefinitionExtensions.cs b/src/Analysis/Ast/Impl/Extensions/FunctionDefinitionExtensions.cs new file mode 100644 index 000000000..6cf42b965 --- /dev/null +++ b/src/Analysis/Ast/Impl/Extensions/FunctionDefinitionExtensions.cs @@ -0,0 +1,13 @@ +using Microsoft.Python.Analysis.Types; + +namespace Microsoft.Python.Analysis { + public static class ClassMemberExtensions { + public static bool IsDunderInit(this IPythonClassMember member) { + return member.Name == "__init__" && member.DeclaringType?.MemberType == PythonMemberType.Class; + } + + public static bool IsDunderNew(this IPythonClassMember member) { + return member.Name == "__new__" && member.DeclaringType?.MemberType == PythonMemberType.Class; + } + } +} diff --git a/src/Analysis/Ast/Impl/Extensions/PythonTypeExtensions.cs b/src/Analysis/Ast/Impl/Extensions/PythonTypeExtensions.cs index d024a35a5..992fb79ea 100644 --- a/src/Analysis/Ast/Impl/Extensions/PythonTypeExtensions.cs +++ b/src/Analysis/Ast/Impl/Extensions/PythonTypeExtensions.cs @@ -37,8 +37,5 @@ public static void TransferDocumentationAndLocation(this IPythonType s, IPythonT dst.Location = src.Location; } } - - public static bool IsConstructor(this IPythonClassMember m) - => m.Name.EqualsOrdinal("__init__") || m.Name.EqualsOrdinal("__new__"); } }