Skip to content
This repository was archived by the owner on Apr 14, 2022. It is now read-only.

Port PR from PTVS: https://github.com/Microsoft/PTVS/pull/4716 #115

Merged
merged 1 commit into from
Sep 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 28 additions & 10 deletions src/Analysis/Engine/Impl/Analyzer/DDG.cs
Original file line number Diff line number Diff line change
Expand Up @@ -454,13 +454,13 @@ private bool TryImportModule(string modName, bool forceAbsolute, out ModuleRefer
return false;
}

internal List<AnalysisValue> LookupBaseMethods(string name, IEnumerable<IAnalysisSet> bases, Node node, AnalysisUnit unit) {
internal List<AnalysisValue> LookupBaseMethods(string name, IEnumerable<IAnalysisSet> mro, Node node, AnalysisUnit unit) {
var result = new List<AnalysisValue>();
foreach (var b in bases) {
foreach (var curType in b) {
var klass = curType as BuiltinClassInfo;
if (klass != null) {
var value = klass.GetMember(node, unit, name);
foreach (var @class in mro.Skip(1)) {
foreach (var curType in @class) {
bool isClass = curType is ClassInfo || curType is BuiltinClassInfo;
if (isClass) {
var value = curType.GetMember(node, unit, name);
if (value != null) {
result.AddRange(value);
}
Expand All @@ -470,7 +470,6 @@ internal List<AnalysisValue> LookupBaseMethods(string name, IEnumerable<IAnalysi
return result;
}


public override bool Walk(FunctionDefinition node) {
InterpreterScope funcScope;
if (_unit.InterpreterScope.TryGetNodeScope(node, out funcScope)) {
Expand Down Expand Up @@ -572,9 +571,28 @@ public override bool Walk(ImportStatement node) {

public override bool Walk(ReturnStatement node) {
var fnScope = CurrentFunction;
if (node.Expression != null && fnScope != null) {
var lookupRes = _eval.Evaluate(node.Expression);
fnScope.AddReturnTypes(node, _unit, lookupRes);
if (fnScope == null || node.Expression == null) {
return true;
}

var lookupRes = _eval.Evaluate(node.Expression);
fnScope.AddReturnTypes(node, _unit, lookupRes);

var function = fnScope.Function;
var analysisUnit = (FunctionAnalysisUnit)function.AnalysisUnit;

if (Scope.OuterScope is ClassScope curClass) {
var bases = LookupBaseMethods(
analysisUnit.Ast.Name,
curClass.Class.Mro,
analysisUnit.Ast,
analysisUnit
);

foreach (FunctionInfo baseFunction in bases.OfType<FunctionInfo>()) {
var baseAnalysisUnit = (FunctionAnalysisUnit)baseFunction.AnalysisUnit;
baseAnalysisUnit.ReturnValue.AddTypes(_unit, lookupRes);
}
}
return true;
}
Expand Down
42 changes: 42 additions & 0 deletions src/Analysis/Engine/Test/InheritanceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Python.LanguageServer.Implementation;
using Microsoft.PythonTools.Analysis.FluentAssertions;
using Microsoft.PythonTools.Interpreter;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestUtilities;

namespace Microsoft.PythonTools.Analysis {
[TestClass]
public class InheritanceTests {
public TestContext TestContext { get; set; }

[TestInitialize]
public void TestInitialize() => TestEnvironmentImpl.TestInitialize($"{TestContext.FullyQualifiedTestClassName}.{TestContext.TestName}");

[TestCleanup]
public void TestCleanup() => TestEnvironmentImpl.TestCleanup();

[TestMethod]
public async Task AbstractMethodReturnTypeIgnored() {
var code = @"import abc
class A:
@abc.abstractmethod
def virt():
pass
class B(A):
def virt():
return 42
a = A()
b = a.virt()";

using (var server = await new Server().InitializeAsync(PythonVersions.Required_Python36X)) {
var analysis = await server.OpenDefaultDocumentAndGetAnalysisAsync(code);

analysis.Should().HaveVariable("b").OfType(BuiltinTypeId.Int);
}
}
}
}