/IronPython_Main/Tools/IronStudio/AnalysisTest/AnalysisTest.cs
C# | 2217 lines | 2070 code | 134 blank | 13 comment | 31 complexity | a2a52c28c45f7322f08e23f6dd8250d3 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0
Large files files are truncated, but you can click here to view the full file
- /* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation.
- *
- * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
- * copy of the license can be found in the License.html file at the root of this distribution. If
- * you cannot locate the Apache License, Version 2.0, please send an email to
- * ironpy@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
- * by the terms of the Apache License, Version 2.0.
- *
- * You must not remove this notice, or any other, from this software.
- *
- * ***************************************************************************/
-
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Numerics;
- using System.Text;
- using IronPython.Hosting;
- using IronPython.Runtime;
- using IronPython.Runtime.Types;
- using Microsoft.IronPythonTools.Intellisense;
- using Microsoft.PyAnalysis;
- using Microsoft.PyAnalysis.Values;
- using Microsoft.Scripting;
- using Microsoft.Scripting.Hosting;
- using Microsoft.Scripting.Hosting.Providers;
- using Microsoft.Scripting.Library;
- using Microsoft.Scripting.Utils;
- using Microsoft.VisualStudio.TestTools.UnitTesting;
- using System.Diagnostics;
- using IronPython.Runtime.Exceptions;
-
- namespace AnalysisTest {
- [TestClass]
- public partial class AnalysisTest {
- private static ScriptEngine _engine;
- private static PythonType PyObjectType, IntType, StringType, FloatType, TypeType, ListType, TupleType, BoolType, FunctionType, ComplexType, GeneratorType;
- private static string[] _objectMembers, _objectMembersClr, _functionMembers;
- private static string[] _strMembers, _strMembersClr;
- private static string[] _listMembers, _intMembers;
-
- public static int Main(string[] args) {
- AnalysisTest test = new AnalysisTest();
-
- if (args.Length > 0 && args[0] == "PERF") {
- args = ArrayUtils.ShiftLeft(args, 1);
- return test.RunTests(args, typeof(PerfMethodAttribute));
- }
-
- return test.RunTests(args, typeof(TestMethodAttribute));
- }
-
- private int RunTests(string[] args, Type testAttr) {
- var fg = Console.ForegroundColor;
- int failures = 0;
- foreach (var mi in typeof(AnalysisTest).GetMethods()) {
- if ((args.Length == 0 || (args.Length > 0 && args.Contains(mi.Name))) &&
- mi.IsDefined(testAttr, false)) {
-
- try {
- mi.Invoke(this, new object[0]);
- Console.ForegroundColor = ConsoleColor.Green;
- Console.WriteLine("Test passed: {0}", mi.Name);
- } catch (Exception e) {
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine("Test failed: {0}", mi.Name);
- Console.ForegroundColor = ConsoleColor.Gray;
- Console.WriteLine(e);
- failures++;
- }
- }
- }
-
- Console.WriteLine();
- if (failures == 0) {
- Console.ForegroundColor = ConsoleColor.Green;
- Console.WriteLine("No failures");
- } else {
- Console.ForegroundColor = ConsoleColor.Red;
- Console.WriteLine("{0} failures", failures);
- }
- Console.ForegroundColor = fg;
- return failures;
- }
-
- #region Test Cases
-
- [TestMethod]
- public void TestImportStar() {
- var entry = ProcessText(@"
- from nt import *
- ");
-
- var members = entry.GetMembers("", 1).Select(x => x.Name);
-
- AssertContains(members, "abort");
-
- entry = ProcessText(@"");
-
- // make sure abort hasn't become a builtin, if so this test needs to be updated
- // with a new name
- members = entry.GetMembers("", 1).Select(x => x.Name);
- foreach (var member in members) {
- if(member == "abort") {
- Assert.Fail("abort has become a builtin, or a clean module includes it for some reason");
- }
- }
- }
-
- [TestMethod]
- public void TestMutatingReferences() {
- var state = new ProjectState(_engine);
-
- var text1 = @"
- import mod2
-
- class C(object):
- def SomeMethod(self):
- pass
-
- mod2.D(C())
- ";
-
- var text2 = @"
- class D(object):
- def __init__(self, value):
- self.value = value
- self.value.SomeMethod()
- ";
-
- var mod1 = ParseText(state, GetSourceUnit(text1, "mod1"), "mod1");
- var mod2 = ParseText(state, GetSourceUnit(text2, "mod2"), "mod2");
-
- VerifyReferences(mod1.Analysis.GetVariables("SomeMethod", GetLineNumber(text1, "SomeMethod")),
- new VariableLocation(5, 5, VariableType.Definition), new VariableLocation(5, 9, VariableType.Reference));
-
- // mutate 1st file
- text1 = text1.Substring(0, text1.IndexOf(" def")) + Environment.NewLine + text1.Substring(text1.IndexOf(" def"));
- Prepare(mod1, GetSourceUnit(text1, "mod1"));
- mod1.Analyze();
-
- VerifyReferences(mod1.Analysis.GetVariables("SomeMethod", GetLineNumber(text1, "SomeMethod")),
- new VariableLocation(6, 5, VariableType.Definition), new VariableLocation(5, 9, VariableType.Reference));
-
- // mutate 2nd file
- text2 = Environment.NewLine + text2;
- Prepare(mod2, GetSourceUnit(text2, "mod1"));
- mod2.Analyze();
-
- VerifyReferences(mod1.Analysis.GetVariables("SomeMethod", GetLineNumber(text1, "SomeMethod")),
- new VariableLocation(6, 5, VariableType.Definition), new VariableLocation(6, 9, VariableType.Reference));
-
- }
-
- /// <summary>
- /// Verify importing wpf will add a reference to the WPF assemblies
- /// </summary>
- [TestMethod]
- public void TestWpfReferences() {
- var entry = ProcessText(@"
- import wpf
- from System.Windows.Media import Colors
- ");
-
- AssertContains(entry.GetMembersFromName("Colors", 1), "Blue");
- }
-
- [TestMethod]
- public void TestGenerator() {
- var entry = ProcessText(@"
- def f():
- yield 1
- yield 2
- yield 3
-
- a = f()
- b = a.next()
-
- for c in f():
- print c
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("a", 1), GeneratorType);
- AssertContainsExactly(entry.GetTypesFromName("b", 1), IntType);
- AssertContainsExactly(entry.GetTypesFromName("c", 1), IntType);
-
- var text = @"
- def f():
- yield 1
- x = yield 2
-
- a = f()
- b = a.next()
- c = a.send('abc')";
- entry = ProcessText(text);
-
- AssertContainsExactly(entry.GetTypesFromName("a", 1), GeneratorType);
- AssertContainsExactly(entry.GetTypesFromName("b", 1), IntType);
- AssertContainsExactly(entry.GetTypesFromName("c", 1), IntType);
- AssertContainsExactly(entry.GetTypesFromName("x", GetLineNumber(text, "yield 2")), StringType);
- }
-
- [TestMethod]
- public void TestEnum() {
- var entry = ProcessText(@"
- import System
- x = System.StringComparison.OrdinalIgnoreCase
- ");
-
- var x = entry.GetValues("x", 1).First();
- Assert.AreEqual(x.ResultType, ResultType.EnumInstance);
- }
-
- /*
- [TestMethod]
- public void TestListComprehensions() {
- var entry = ProcessText(@"
- x = [2,3,4]
- y = [a for a in x]
- z = y[0]
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("z", 0), IntType);
- }*/
-
- [TestMethod]
- public void TestForSequence() {
- var entry = ProcessText(@"
- x = [('abc', 42, True), ('abc', 23, False),]
- for some_str, some_int, some_bool in x:
- print some_str
- print some_int
- print some_bool
- ");
- AssertContainsExactly(entry.GetTypesFromName("some_str", 1), StringType);
- AssertContainsExactly(entry.GetTypesFromName("some_int", 1), IntType);
- AssertContainsExactly(entry.GetTypesFromName("some_bool", 1), BoolType);
- }
-
- [TestMethod]
- public void TestDynamicAttributes() {
- var entry = ProcessText(@"
- class x(object):
- def __getattr__(self, name):
- return 42
- def f(self):
- return 'abc'
-
- a = x().abc
- b = x().f()
-
- class y(object):
- def __getattribute__(self, x):
- return 'abc'
-
- c = y().abc
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("a", 1), IntType);
- AssertContainsExactly(entry.GetTypesFromName("b", 1), StringType);
- AssertContainsExactly(entry.GetTypesFromName("c", 1), StringType);
- }
-
- [TestMethod]
- public void TestListAppend() {
- var entry = ProcessText(@"
- x = []
- x.append('abc')
- y = x[0]
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("y", 1), StringType);
-
- entry = ProcessText(@"
- x = []
- x.extend(('abc', ))
- y = x[0]
- ");
- AssertContainsExactly(entry.GetTypesFromName("y", 1), StringType);
-
- entry = ProcessText(@"
- x = []
- x.insert(0, 'abc')
- y = x[0]
- ");
- AssertContainsExactly(entry.GetTypesFromName("y", 1), StringType);
-
- entry = ProcessText(@"
- x = []
- x.append('abc')
- y = x.pop()
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("y", 1), StringType);
-
- entry = ProcessText(@"
- class ListTest(object):
- def reset(self):
- self.items = []
- self.pushItem(self)
- def pushItem(self, item):
- self.items.append(item)
-
- a = ListTest()
- b = a.items[0]");
-
- AssertContains(entry.GetMembersFromName("b", 1), "pushItem");
- }
-
- [TestMethod]
- public void TestSlicing() {
- var entry = ProcessText(@"
- x = [2]
- y = x[:-1]
- z = y[0]
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("z", 1), IntType);
-
- entry = ProcessText(@"
- x = (2, 3, 4)
- y = x[:-1]
- z = y[0]
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("z", 1), IntType);
- }
-
- [TestMethod]
- public void TestColor() {
-
- var entry = ProcessText(@"
- import clr
- clr.AddReference('PresentationFramework')
- clr.AddReference('PresentationCore')
-
- from System.Windows.Media import Colors
-
- class C(object):
- def __init__(self):
- if False:
- self.some_color = Colors.Black
- else:
- self.some_color = Colors.White
-
-
- a = C()
- b = a.some_color
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("b", 1).Select(x => PythonType.Get__name__(x)), "Color");
- }
-
- [TestMethod]
- public void TestConstantIndex() {
- var entry = ProcessText(@"
- ZERO = 0
- ONE = 1
- TWO = 2
- x = ['abc', 42, True)]
-
-
- some_str = x[ZERO]
- some_int = x[ONE]
- some_bool = x[TWO]
- ");
- AssertContainsExactly(entry.GetTypesFromName("some_str", 1), StringType);
- AssertContainsExactly(entry.GetTypesFromName("some_int", 1), IntType);
- AssertContainsExactly(entry.GetTypesFromName("some_bool", 1), BoolType);
- }
- [TestMethod]
- public void TestCtorSignatures() {
- var entry = ProcessText(@"
- class C: pass
-
- class D(object): pass
-
- class E(object):
- def __init__(self): pass
-
- class F(object):
- def __init__(self, one): pass
-
- class G(object):
- def __new__(cls): pass
-
- class H(object):
- def __new__(cls, one): pass
-
- ");
-
- var result = entry.GetSignatures("C", 1).ToArray();
- Assert.AreEqual(result.Length, 1);
- Assert.AreEqual(result[0].Parameters.Length, 0);
-
- result = entry.GetSignatures("D", 1).ToArray();
- Assert.AreEqual(result.Length, 1);
- Assert.AreEqual(result[0].Parameters.Length, 0);
-
- result = entry.GetSignatures("E", 1).ToArray();
- Assert.AreEqual(result.Length, 1);
- Assert.AreEqual(result[0].Parameters.Length, 0);
-
- result = entry.GetSignatures("F", 1).ToArray();
- Assert.AreEqual(result.Length, 1);
- Assert.AreEqual(result[0].Parameters.Length, 1);
-
- result = entry.GetSignatures("G", 1).ToArray();
- Assert.AreEqual(result.Length, 1);
- Assert.AreEqual(result[0].Parameters.Length, 0);
-
- result = entry.GetSignatures("H", 1).ToArray();
- Assert.AreEqual(result.Length, 1);
- Assert.AreEqual(result[0].Parameters.Length, 1);
- }
-
- [TestMethod]
- public void TestBuiltinTypeSignatures() {
- var entry = ProcessText(@"
- import System
- x = str
- x = int
-
- y = str
- y = int
- ");
-
- var result = entry.GetSignatures("System.Collections.Generic.Dictionary[int, int]", 1).ToArray();
- Assert.AreEqual(result.Length, 6);
-
- // 2 possible types
- result = entry.GetSignatures("System.Collections.Generic.Dictionary[x, int]", 1).ToArray();
- Assert.AreEqual(result.Length, 12);
-
- // 4 possible types
- result = entry.GetSignatures("System.Collections.Generic.Dictionary[x, y]", 1).ToArray();
- Assert.AreEqual(result.Length, 24);
- }
-
- [TestMethod]
- public void TestBuiltinMethodSignatures() {
- var entry = ProcessText(@"
- const = """".capitalize
- constructed = str().capitalize
- ");
-
- string[] testCapitalize = new[] { "const", "constructed" };
- foreach (var test in testCapitalize) {
- var result = entry.GetSignatures(test, 1).ToArray();
- Assert.AreEqual(result.Length, 1);
- Assert.AreEqual(result[0].Parameters.Length, 0);
- }
-
- entry = ProcessText(@"
- import clr
- const = """".Contains
- constructed = str().Contains
- ");
-
- string[] testContains = new[] { "const", "constructed" };
- foreach (var test in testContains) {
- var result = entry.GetSignatures(test, 1).ToArray();
- Assert.AreEqual(result.Length, 1);
- Assert.AreEqual(result[0].Parameters.Length, 1);
- Assert.AreEqual(result[0].Parameters[0].Name, "value");
- Assert.AreEqual(result[0].Parameters[0].IsOptional, false);
- }
- }
-
- [TestMethod]
- public void TestDel() {
- string text = @"
- del foo
- del foo[2]
- del foo.bar
- del (foo)
- del foo, bar
- ";
- var entry = ProcessText(text);
-
- // We do no analysis on del statements, nothing to test
- }
-
- [TestMethod]
- public void TryExcept() {
- string text = @"
- class MyException(Exception): pass
-
- def f():
- try:
- except TypeError, e1:
- pass
-
- def g():
- try:
- except MyException, e2:
- pass
- ";
- var entry = ProcessText(text);
-
- AssertContainsExactly(GetTypes(entry.GetValues("e1", GetLineNumber(text, ", e1"))), PythonExceptions.TypeError);
-
- AssertContainsExactly(GetTypeNames(entry.GetValues("e2", GetLineNumber(text, ", e2"))), "MyException instance");
- }
-
- private IEnumerable<PythonType> GetTypes(IEnumerable<IAnalysisValue> analysisValues) {
- foreach (var value in analysisValues) {
- yield return value.PythonType;
- }
- }
-
- private IEnumerable<string> GetTypeNames(IEnumerable<IAnalysisValue> analysisValues) {
- foreach (var value in analysisValues) {
- yield return value.ShortDescription;
- }
- }
-
- class VariableLocation {
- public readonly int StartLine;
- public readonly int StartCol;
- public readonly VariableType Type;
-
- public VariableLocation(int startLine, int startCol, VariableType type) {
- StartLine = startLine;
- StartCol = startCol;
- Type = type;
- }
- }
-
- [TestMethod]
- public void TestReferences() {
- // instance variables
- var text = @"
- # add ref w/o type info
- class C(object):
- def __init__(self, foo):
- self.abc = foo
- del self.abc
- print self.abc
-
- ";
- var entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("self.abc", GetLineNumber(text, "self.abc")), new VariableLocation(5, 9, VariableType.Definition), new VariableLocation(6, 13, VariableType.Reference), new VariableLocation(7, 15, VariableType.Reference));
- VerifyReferences(entry.GetVariables("foo", GetLineNumber(text, "foo")), new VariableLocation(4, 24, VariableType.Definition), new VariableLocation(5, 20, VariableType.Reference));
-
- text = @"
- # add ref w/ type info
- class D(object):
- def __init__(self, foo):
- self.abc = foo
- del self.abc
- print self.abc
-
- D(42)";
- entry = ProcessText(text);
-
- VerifyReferences(entry.GetVariables("self.abc", GetLineNumber(text, "self.abc")), new VariableLocation(5, 9, VariableType.Definition), new VariableLocation(6, 13, VariableType.Reference), new VariableLocation(7, 15, VariableType.Reference));
- VerifyReferences(entry.GetVariables("foo", GetLineNumber(text, "foo")), new VariableLocation(4, 24, VariableType.Definition), new VariableLocation(5, 20, VariableType.Reference));
- VerifyReferences(entry.GetVariables("D", GetLineNumber(text, "D(42)")), new VariableLocation(9, 1, VariableType.Reference), new VariableLocation(3, 1, VariableType.Definition));
-
- // function definitions
- text = @"
- def f(): pass
-
- x = f()";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("f", GetLineNumber(text, "x =")), new VariableLocation(4, 5, VariableType.Reference), new VariableLocation(2, 1, VariableType.Definition));
-
- text = @"
- from System import EventHandler
- def g():
- x = EventHandler(f)
-
- def f(sender, args): pass
- ";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("f", GetLineNumber(text, "x =")), new VariableLocation(4, 22, VariableType.Reference), new VariableLocation(6, 1, VariableType.Definition));
-
- text = @"
- from System import EventHandler
- def f(sender, args): pass
-
- x = EventHandler(f)";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("f", GetLineNumber(text, "x =")), new VariableLocation(5, 18, VariableType.Reference), new VariableLocation(3, 1, VariableType.Definition));
-
- // left hand side is unknown, right hand side should still have refs added
- text = @"
- from System import EventHandler
- def f(sender, args): pass
-
- a.foo += EventHandler(f)
- ";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("f", GetLineNumber(text, "a.foo +=")), new VariableLocation(5, 23, VariableType.Reference), new VariableLocation(3, 1, VariableType.Definition));
-
-
- text = @"
- def f(): pass
-
- x = f";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("f", GetLineNumber(text, "x =")), new VariableLocation(4, 5, VariableType.Reference), new VariableLocation(2, 1, VariableType.Definition));
-
- // class variables
- text = @"
-
- class D(object):
- abc = 42
- print abc
- del abc
- ";
- entry = ProcessText(text);
-
- VerifyReferences(entry.GetVariables("abc", GetLineNumber(text, "abc =")), new VariableLocation(4, 5, VariableType.Definition), new VariableLocation(5, 11, VariableType.Reference), new VariableLocation(6, 9, VariableType.Reference));
-
- // class definition
- text = @"
- class D(object): pass
-
- a = D
- ";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("D", GetLineNumber(text, "a =")), new VariableLocation(4, 5, VariableType.Reference), new VariableLocation(2, 1, VariableType.Definition));
-
- // method definition
- text = @"
- class D(object):
- def f(self): pass
-
- a = D().f()
- ";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("D().f", GetLineNumber(text, "a =")),
- new VariableLocation(5, 5, VariableType.Reference), new VariableLocation(3, 5, VariableType.Definition));
-
- // globals
- text = @"
- abc = 42
- print abc
- del abc
- ";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("abc", GetLineNumber(text, "abc =")), new VariableLocation(4, 5, VariableType.Reference), new VariableLocation(2, 1, VariableType.Definition), new VariableLocation(3, 7, VariableType.Reference));
-
- // parameters
- text = @"
- def f(abc):
- print abc
- abc = 42
- del abc
- ";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("abc", GetLineNumber(text, "abc =")), new VariableLocation(2, 7, VariableType.Definition), new VariableLocation(4, 5, VariableType.Definition), new VariableLocation(3, 11, VariableType.Reference), new VariableLocation(5, 9, VariableType.Reference));
-
-
- // grammer test - statements
- text = @"
- def f(abc):
- try: pass
- except abc: pass
-
- try: pass
- except TypeError, abc: pass
-
- abc, bar = 42, 23
- abc[23] = 42
- abc.foo = 42
- abc += 2
-
- class D(abc): pass
-
- for x in abc: print x
-
- import abc
- from xyz import abc
- from xyz import bar as abc
-
- if abc: print 'hi'
- elif abc: print 'bye'
- else: abc
-
- with abc:
- return abc
-
- print abc
- assert abc, abc
-
- raise abc
- raise abc, abc, abc
-
- while abc:
- abc
- else:
- abc
-
- for x in foo:
- print x
- else:
- print abc
-
- try: pass
- except TypeError:
- else:
- abc
- ";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("abc", GetLineNumber(text, "f(abc)")),
- new VariableLocation(2, 7, VariableType.Definition),
- new VariableLocation(4, 12, VariableType.Reference),
- new VariableLocation(7, 23, VariableType.Definition),
-
- new VariableLocation(9, 5, VariableType.Definition),
- new VariableLocation(10, 5, VariableType.Reference),
- new VariableLocation(11, 5, VariableType.Reference),
- new VariableLocation(12, 5, VariableType.Reference),
-
- new VariableLocation(14, 13, VariableType.Reference),
-
- new VariableLocation(16, 14, VariableType.Reference),
-
- new VariableLocation(18, 5, VariableType.Reference),
- new VariableLocation(19, 5, VariableType.Reference),
- new VariableLocation(20, 5, VariableType.Reference),
-
- new VariableLocation(22, 8, VariableType.Reference),
- new VariableLocation(23, 10, VariableType.Reference),
- new VariableLocation(24, 11, VariableType.Reference),
-
- new VariableLocation(26, 10, VariableType.Reference),
- new VariableLocation(27, 16, VariableType.Reference),
-
- new VariableLocation(29, 11, VariableType.Reference),
- new VariableLocation(30, 12, VariableType.Reference),
- new VariableLocation(30, 17, VariableType.Reference),
-
- new VariableLocation(32, 11, VariableType.Reference),
- new VariableLocation(33, 11, VariableType.Reference),
- new VariableLocation(33, 16, VariableType.Reference),
- new VariableLocation(33, 21, VariableType.Reference),
-
- new VariableLocation(35, 11, VariableType.Reference),
- new VariableLocation(36, 9, VariableType.Reference),
- new VariableLocation(38, 9, VariableType.Reference),
-
- new VariableLocation(43, 15, VariableType.Reference),
-
- new VariableLocation(48, 9, VariableType.Reference)
- );
-
-
- // grammer test - expressions
- text = @"
- def f(abc):
- x = abc + 2
- x = 2 + abc
- x = l[abc]
- x = abc[l]
- x = abc.foo
-
- g(abc)
-
- abc if abc else abc
-
- {abc:abc},
- [abc, abc]
- (abc, abc)
- {abc}
-
- yield abc
- [x for x in abc]
- (x for x in abc)
-
- abc or abc
- abc and abc
-
- +abc
- x[abc:abc:abc]
-
- abc == abc
- not abc
-
- lambda : abc
- ";
- entry = ProcessText(text);
- VerifyReferences(entry.GetVariables("abc", GetLineNumber(text, "f(abc)")),
- new VariableLocation(2, 7, VariableType.Definition),
-
- new VariableLocation(3, 9, VariableType.Reference),
- new VariableLocation(4, 13, VariableType.Reference),
-
- new VariableLocation(5, 10, VariableType.Reference), // BUGBUG: should be 5,11
- new VariableLocation(6, 9, VariableType.Reference),
- new VariableLocation(7, 9, VariableType.Reference),
- new VariableLocation(9, 7, VariableType.Reference),
-
- new VariableLocation(11, 5, VariableType.Reference),
- new VariableLocation(11, 12, VariableType.Reference),
- new VariableLocation(11, 21, VariableType.Reference),
-
- new VariableLocation(13, 6, VariableType.Reference),
- new VariableLocation(13, 10, VariableType.Reference),
- new VariableLocation(14, 6, VariableType.Reference),
- new VariableLocation(14, 11, VariableType.Reference),
- new VariableLocation(15, 6, VariableType.Reference),
- new VariableLocation(15, 11, VariableType.Reference),
- new VariableLocation(16, 6, VariableType.Reference),
-
- new VariableLocation(18, 11, VariableType.Reference),
- new VariableLocation(19, 17, VariableType.Reference),
- new VariableLocation(20, 17, VariableType.Reference),
-
- new VariableLocation(22, 5, VariableType.Reference),
- new VariableLocation(22, 12, VariableType.Reference),
- new VariableLocation(23, 5, VariableType.Reference),
- new VariableLocation(23, 13, VariableType.Reference),
-
- new VariableLocation(25, 6, VariableType.Reference),
- new VariableLocation(26, 7, VariableType.Reference),
- new VariableLocation(26, 11, VariableType.Reference),
- new VariableLocation(26, 15, VariableType.Reference),
-
- new VariableLocation(28, 5, VariableType.Reference),
- new VariableLocation(28, 12, VariableType.Reference),
- new VariableLocation(29, 9, VariableType.Reference)
-
- //new VariableLocation(30, 14, VariableType.Reference) // BUGBUG: Enable when lambda bodies are walked
- );
- }
-
- private void VerifyReferences(IEnumerable<IAnalysisVariable> variables, params VariableLocation[] variableType) {
- var vars = new List<IAnalysisVariable>(variables);
- if (vars.Count == 0) {
- Assert.Fail("Got no references");
- }
-
- int removed = 0;
- bool removedOne = false;
- do {
- for (int j = 0; j < variableType.Length; j++) {
- var expected = variableType[j];
-
- bool found = false;
- for (int i = 0; i < vars.Count; i++) {
- var have = vars[i];
-
- if (have.Location.Line == expected.StartLine &&
- have.Location.Column == expected.StartCol &&
- have.Type == expected.Type) {
- vars.RemoveAt(i);
- removed++;
- removedOne = found = true;
- break;
- }
- }
-
- if (!found) {
- StringBuilder error = new StringBuilder(String.Format("Failed to find location: {0} {1} {2}" + Environment.NewLine, expected.StartLine, expected.StartCol, expected.Type));
- LocationNames(vars, error);
-
- Assert.Fail(error.ToString());
- }
- }
- } while (vars.Count != 0 && removedOne);
-
- if (vars.Count != 0) {
- StringBuilder error = new StringBuilder("Didn't use all locations - had " + variables.Count() + Environment.NewLine);
- LocationNames(vars, error);
- Assert.Fail(error.ToString());
- }
- }
-
- private static void LocationNames(List<IAnalysisVariable> vars, StringBuilder error) {
- foreach (var var in vars) {
- error.AppendFormat(" {0} {1} {2}", var.Location.Line, var.Location.Column, var.Type);
- error.AppendLine();
- }
- }
-
- [TestMethod]
- public void TestSignatureDefaults() {
- var entry = ProcessText(@"
- def f(x = None): pass
-
- def g(x = {}): pass
-
- def h(x = {2:3}): pass
-
- def i(x = []): pass
-
- def j(x = [None]): pass
-
- def k(x = ()): pass
-
- def l(x = (2, )): pass
- ");
-
- var tests = new[] {
- new { FuncName = "f", ParamName="x = None" },
- new { FuncName = "g", ParamName="x = {}" },
- new { FuncName = "h", ParamName="x = {...}" },
- new { FuncName = "i", ParamName="x = []" },
- new { FuncName = "j", ParamName="x = [...]" },
- new { FuncName = "k", ParamName="x = ()" },
- new { FuncName = "l", ParamName="x = (...)" },
- };
-
- foreach (var test in tests) {
- var result = entry.GetSignatures(test.FuncName, 1).ToArray();
- Assert.AreEqual(result.Length, 1);
- Assert.AreEqual(result[0].Parameters[0].Name, test.ParamName);
- }
- }
-
- [TestMethod]
- public void TestGetVariablesDictionaryGet() {
- var entry = ProcessText(@"
- x = {42:'abc'}
- ");
-
- foreach (var varRef in entry.GetValues("x.get", 1)) {
- Assert.AreEqual("built-in method get", varRef.Description);
- }
- }
-
- [TestMethod]
- public void TestLambdaExpression() {
- var entry = ProcessText(@"
- x = lambda a: a
- y = x(42)
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("y", 1), IntType);
-
- entry = ProcessText(@"
- def f(a):
- return a
-
- x = lambda b: f(b)
- y = x(42)
- ");
-
- AssertContainsExactly(entry.GetTypesFromName("y", 1), IntType);
- }
-
- [TestMethod]
- public void TestRecursiveClass() {
- var entry = ProcessText(@"
- cls = object
-
- class cls(cls):
- abc = 42
- ");
-
- entry.GetMembersFromName("cls", 1);
- AssertContainsExactly(entry.GetMembers("cls().abc.", 1).Select(member => member.Name), _intMembers);
- AssertContainsExactly(entry.GetMembers("cls.abc.", 1).Select(member => member.Name), _intMembers);
- }
-
- [TestMethod]
- public void TestBadMethod() {
- var entry = ProcessText(@"
- class cls(object):
- def f():
- return 42
-
- abc = cls()
- foo = abc.f()
- ");
-
- AssertContainsExactly(entry.GetMembers("foo.", 1).Select(member => member.Name), _intMembers);
- }
-
- [TestMethod]
- public void TestKeywordArguments() {
- var funcDef = "def f(a, b, c): pass";
- var classWithInit = @"class f(object):
- def __init__(self, a, b, c):
- pass";
- var classWithNew = @"class f(object):
- def __new__(cls, a, b, c):
- pass";
- var method = @"class x(object):
- def g(self, a, b, c):
- pass
-
- f = x().g";
- var decls = new [] { funcDef, classWithInit, classWithNew, method };
-
- foreach (var decl in decls) {
- string[] testCalls = new[] {
- "f(c = 'abc', b = 42, a = 3j)", "f(3j, c = 'abc', b = 42)", "f(3j, 42, c = 'abc')",
- "f(c = 'abc', b = 42, a = 3j, d = 42)", // extra argument
- "f(3j, 42, 'abc', d = 42)",
- };
-
- foreach (var testCall in testCalls) {
- var text = decl + Environment.NewLine + testCall;
- var entry = ProcessText(text);
-
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "pass")), ComplexType);
- AssertContainsExactly(entry.GetTypesFromName("b", GetLineNumber(text, "pass")), IntType);
- AssertContainsExactly(entry.GetTypesFromName("c", GetLineNumber(text, "pass")), StringType);
- }
- }
- }
-
- [TestMethod]
- public void TestPositionalSplat() {
- var funcDef = "def f(a, b, c): pass";
- var classWithInit = @"class f(object):
- def __init__(self, a, b, c):
- pass";
- var classWithNew = @"class f(object):
- def __new__(cls, a, b, c):
- pass";
- var method = @"class x(object):
- def g(self, a, b, c):
- pass
-
- f = x().g";
- var decls = new[] { funcDef, classWithInit, classWithNew, method };
-
- foreach (var decl in decls) {
- string[] testCalls = new[] {
- "f(*(3j, 42, 'abc'))",
- "f(*[3j, 42, 'abc'])",
- "f(*(3j, 42, 'abc', 4L))", // extra argument
- "f(*[3j, 42, 'abc', 4L])", // extra argument
- };
-
- foreach (var testCall in testCalls) {
- var text = decl + Environment.NewLine + testCall;
- var entry = ProcessText(text);
-
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "pass")), ComplexType);
- AssertContainsExactly(entry.GetTypesFromName("b", GetLineNumber(text, "pass")), IntType);
- AssertContainsExactly(entry.GetTypesFromName("c", GetLineNumber(text, "pass")), StringType);
- }
- }
- }
- [TestMethod]
- public void TestForwardRef() {
- var text = @"
-
- class D(object):
- def bar(self, x):
- abc = C()
- abc.foo(2)
- a = abc.foo(2.0)
- a.bar(('a', 'b', 'c', 'd'))
-
- class C(object):
- def foo(self, x):
- D().bar('abc')
- D().bar(['a', 'b', 'c'])
- return D()
- def baz(self): pass
- ";
- var entry = ProcessText(text);
-
- var fifty = entry.GetVariablesNoBuiltins(GetLineNumber(text, "abc.foo")).ToSet();
- AssertContainsExactly(fifty, "C", "D", "a", "abc", "self", "x");
-
- var three = entry.GetVariablesNoBuiltins(GetLineNumber(text, "lass D")).ToSet();
- AssertContainsExactly(three, "C", "D", "bar");
-
- var allFifty = entry.GetMembersFromName("abc", GetLineNumber(text, "abc.foo")).ToSet();
- AssertContainsExactly(allFifty, GetUnion(_objectMembers, "baz", "foo"));
-
- var xTypes = entry.GetTypesFromName("x", GetLineNumber(text, "abc.foo")).ToSet();
- AssertContainsExactly(xTypes, ListType, StringType, TupleType);
-
- var xMembers = entry.GetMembersFromName("x", GetLineNumber(text, "abc.foo")).ToSet();
- AssertContainsExactly(xMembers, GetIntersection(_strMembers, _listMembers));
- }
-
- private static int GetLineNumber(string text, string substring) {
- string[] splitLines = text.Split('\n');
- for (int i = 0; i < splitLines.Length; i++) {
- if (splitLines[i].IndexOf(substring) != -1) {
- return i + 1;
- }
- }
-
- throw new InvalidOperationException();
- }
-
- [TestMethod]
- public void TestBuiltins() {
- var text = @"
- booltypetrue = True
- booltypefalse = False
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("booltypetrue", 1), BoolType);
- AssertContainsExactly(entry.GetTypesFromName("booltypefalse", 1), BoolType);
- }
-
- [TestMethod]
- public void TestDictionaryFunctionTable() {
- var text = @"
- def f(a, b):
- print a, b
-
- def g(a, b):
- x, y = a, b
-
- x = {'foo': f, 'bar' : g}
- x['foo'](42, [])
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "print")), IntType);
- AssertContainsExactly(entry.GetTypesFromName("b", GetLineNumber(text, "print")), ListType);
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "x, y")), IntType);
- AssertContainsExactly(entry.GetTypesFromName("b", GetLineNumber(text, "x, y")), ListType);
- }
-
- [TestMethod]
- public void TestDictionaryAssign() {
- var text = @"
- x = {'abc': 42}
- y = x['foo']
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("y", 1), IntType);
- }
-
- [TestMethod]
- public void TestDictionaryFunctionTableGet2() {
- var text = @"
- def f(a, b):
- print a, b
-
- def g(a, b):
- x, y = a, b
-
- x = {'foo': f, 'bar' : g}
- x.get('foo')(42, [])
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "print")), IntType);
- AssertContainsExactly(entry.GetTypesFromName("b", GetLineNumber(text, "print")), ListType);
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "x, y")), IntType);
- AssertContainsExactly(entry.GetTypesFromName("b", GetLineNumber(text, "x, y")), ListType);
- }
-
- [TestMethod]
- public void TestDictionaryFunctionTableGet() {
- var text = @"
- def f(a, b):
- print a, b
-
- def g(a, b):
- x, y = a, b
-
- x = {'foo': f, 'bar' : g}
- y = x.get('foo', None)
- if y is not None:
- y(42, [])
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "print")), IntType);
- AssertContainsExactly(entry.GetTypesFromName("b", GetLineNumber(text, "print")), ListType);
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "x, y")), IntType);
- AssertContainsExactly(entry.GetTypesFromName("b", GetLineNumber(text, "x, y")), ListType);
- }
-
- [TestMethod]
- public void TestSimpleGlobals() {
- var text = @"
- class x(object):
- def abc(self):
- pass
-
- a = x()
- x.abc()
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetVariablesNoBuiltins(1), "a", "x");
- AssertContainsExactly(entry.GetMembersFromName("x", 1), GetUnion(_objectMembers, "abc"));
- }
-
- [TestMethod]
- public void TestFuncCallInIf() {
- var text = @"
- def Method(a, b, c):
- print a, b, c
-
- if not Method(42, 'abc', []):
- pass
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "print")), IntType);
- AssertContainsExactly(entry.GetTypesFromName("b", GetLineNumber(text, "print")), StringType);
- AssertContainsExactly(entry.GetTypesFromName("c", GetLineNumber(text, "print")), ListType);
- }
-
- [TestMethod]
- public void TestWithStatement() {
- var text = @"
- class x(object):
- def x_method(self):
- pass
-
- with x() as foo:
- print foo
-
- with x():
- pass
- ";
- var entry = ProcessText(text);
- var foo = entry.GetMembersFromName("foo", GetLineNumber(text, "print foo"));
- AssertContainsExactly(foo, GetUnion(_objectMembers, "x_method"));
- }
-
- [TestMethod]
- public void TestOverrideFunction() {
- var text = @"
- class bar(object):
- def Call(self, xvar, yvar):
- pass
-
- class baz(bar):
- def Call(self, xvar, yvar):
- pass
-
- class Cxxxx(object):
- def __init__(self):
- self.foo = baz()
-
- def Cmeth(self, avar, bvar):
- self.foo.Call(avar, bvar)
-
-
-
- abc = Cxxxx()
- abc.Cmeth(['foo'], 'bar')
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("xvar", GetLineNumber(text, "pass")), ListType);
- }
-
- [TestMethod]
- public void TestSimpleMethodCall() {
- var text = @"
- class x(object):
- def abc(self, foo):
- pass
-
- a = x()
- a.abc('abc')
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("foo", GetLineNumber(text, "pass")), StringType);
- AssertContainsExactly(entry.GetMembersFromName("self", GetLineNumber(text, "pass")), GetUnion(_objectMembers, "abc"));
- }
-
- [TestMethod]
- public void TestSystemFromImport() {
- var text = @"
- from System import Environment
- Environment.GetCommandLineArgs()
- ";
- var entry = ProcessText(text);
- Assert.IsTrue(entry.GetMembersFromName("Environment", 1).Any(s => s == "CommandLine"));
- }
-
- [TestMethod]
- public void TestImportAs() {
- var text = @"
- import System.Collections as coll
- ";
- var entry = ProcessText(text);
- Assert.IsTrue(entry.GetMembersFromName("coll", 1).Any(s => s == "ArrayList"));
- }
-
- [TestMethod]
- public void TestSystemImport() {
- var text = @"
- import System
- System.Environment.GetCommandLineArgs()
- x = System.Environment
- ";
- var entry = ProcessText(text);
- var system = entry.GetMembersFromName("System", 1).ToSet();
- // defined in mscorlib
- AssertContains(system, "AccessViolationException");
- // defined in System
- AssertContains(system, "CodeDom");
-
- AssertContains(entry.GetMembersFromName("x", 1), "GetEnvironmentVariables");
- }
-
- [TestMethod]
- public void TestSystemMembers() {
- var text = @"
- import System
- System.Environment.GetCommandLineArgs()
- x = System.Environment
- args = x.GetCommandLineArgs()
- ";
- var entry = ProcessText(text);
-
- var args = entry.GetTypesFromName("args", GetLineNumber(text, "args =")).ToSet();
- AssertContainsExactly(args, ClrModule.GetPythonType(typeof(string[])));
-
- Assert.IsTrue(entry.GetMembersFromName("args", GetLineNumber(text, "args =")).Any(s => s == "AsReadOnly"));
- }
-
- [TestMethod]
- public void TestNamespaceMembers() {
- var text = @"
- import System
- x = System.Collections
- ";
- var entry = ProcessText(text);
- var x = entry.GetMembersFromName("x", GetLineNumber(text, "x =")).ToSet();
- Assert.IsTrue(x.Contains("Generic"));
- Assert.IsTrue(x.Contains("ArrayList"));
- }
-
- [TestMethod]
- public void TestBuiltinRetval() {
- var text = @"
- x = [2,3,4]
- a = x.index(2)
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("x", GetLineNumber(text, "x =")).ToSet(), ListType);
- AssertContainsExactly(entry.GetTypesFromName("a", GetLineNumber(text, "a =")).ToSet(), IntType);
- }
-
- [TestMethod]
- public void TestBuiltinFuncRetval() {
- var text = @"
- x = ord('a')
- y = range(5)
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("x", GetLineNumber(text, "x = ")).ToSet(), IntType);
- AssertContainsExactly(entry.GetTypesFromName("y", GetLineNumber(text, "y = ")).ToSet(), ListType);
- }
-
- [TestMethod]
- public void TestFunctionMembers() {
- var text = @"
- def f(x): pass
- f.abc = 32
- ";
- var entry = ProcessText(text);
- AssertContains(entry.GetMembersFromName("f", 1), "abc");
-
- text = @"
- def f(x): pass
-
- ";
- entry = ProcessText(text);
- AssertDoesntContain(entry.GetMembersFromName("f", 1), "x");
- AssertContainsExactly(entry.GetMembersFromName("f", 1), _functionMembers);
-
- AssertContainsExactly(entry.GetMembersFromName("f.func_name", 1), _strMembers);
- }
-
-
- [TestMethod]
- public void TestRangeIteration() {
- var text = @"
- for i in range(5):
- pass
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("i", GetLineNumber(text, "for i")).ToSet(), IntType);
- }
-
- [TestMethod]
- public void TestBuiltinImport() {
- var text = @"
- import sys
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetVariablesNoBuiltins(1), "sys");
- Assert.IsTrue(entry.GetMembersFromName("sys", 1).Any((s) => s == "winver"));
- }
-
- [TestMethod]
- public void TestBuiltinImportInFunc() {
- var text = @"
- def f():
- import sys
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetVariablesNoBuiltins(GetLineNumber(text, "sys")), "f", "sys");
- AssertContains(entry.GetMembersFromName("sys", GetLineNumber(text, "sys")), "winver");
- }
-
- [TestMethod]
- public void TestBuiltinImportInClass() {
- var text = @"
- class C:
- import sys
- ";
- var entry = ProcessText(text);
-
- AssertContainsExactly(entry.GetVariablesNoBuiltins(GetLineNumber(text, "sys")), "C", "sys");
- Assert.IsTrue(entry.GetMembersFromName("sys", GetLineNumber(text, "sys")).Any((s) => s == "winver"));
- }
-
- [TestMethod]
- public void TestNoImportClr() {
- var text = @"
- x = 'abc'
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetTypesFromName("x", 1), StringType);
- AssertContainsExactly(entry.GetMembersFromName("x", 1), _strMembers);
- }
-
- [TestMethod]
- public void TestImportClr() {
- var text = @"
- import clr
- x = 'abc'
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetMembersFromName("x", 1), _strMembersClr);
- }
-
- [TestMethod]
- public void TestClrAddReference() {
- var text = @"
- import clr
- clr.AddReference('System.Drawing')
- from System.Drawing import Point
- ";
- var entry = ProcessText(text);
- Assert.AreEqual(35, entry.GetMembersFromName("Point", GetLineNumber(text, "from System.")).ToList().Count);
- }
-
- [TestMethod]
- public void TestClrAddReferenceByName() {
- var text = @"
- import clr
- clr.AddReferenceByName('Microsoft.Scripting')
- from Microsoft.Scripting import SourceUnit
- ";
- var entry = ProcessText(text);
- Assert.AreEqual(40, entry.GetMembersFromName("SourceUnit", GetLineNumber(text, "from Microsoft.")).ToList().Count);
- }
-
- [TestMethod]
- public void TestMutualRecursion() {
- var text = @"
- class C:
- def f(self, other, depth):
- if depth == 0:
- return 'abc'
- return other.g(self, depth - 1)
-
- class D:
- def g(self, other, depth):
- if depth == 0:
- return ['d', 'e', 'f']
-
- return other.f(self, depth - 1)
-
- x = D().g(C(), 42)
-
- ";
- var entry = ProcessText(text);
- AssertContainsExactly(entry.GetMembersFromName("other", GetLineNumber(text, "other.g")), "g");
- AssertContainsExactly(entry.GetTypesFromName("x", GetLineNumber(text, "x =")), ListType, StringType);
- AssertContainsExactly(entry.GetMembersFromName("x", GetLineNumber(text, "x =")),
- GetIntersection(_listMembers, _strMembers));
- }
-
- [TestMethod]
- public void TestForwardRefVars() {
- var text = @"
- class x(object):
- def __init__(self, val):
- self.abc = []
-
- x(42)
- x('abc')
- x([])
- ";
- var entry = ProcessText(text);
- Assert.AreEqual(1, entry.GetValues("self.abc", GetLineNumber(text, "self.abc")).ToList().Count);
- …
Large files files are truncated, but you can click here to view the full file