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

Commit 406a3a4

Browse files
author
Mikhail Arkhipov
authored
Merge pull request #92 from MikhailArkhipov/84
Fix existing and potentil null references
2 parents 64e9503 + 0dbaf33 commit 406a3a4

27 files changed

+192
-240
lines changed

src/Analysis/Engine/Impl/AnalysisUnit.cs

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -369,15 +369,15 @@ internal override void AnalyzeWorker(DDG ddg, CancellationToken cancel) {
369369
var classInfo = ((ClassScope)Scope).Class;
370370
var bases = new List<IAnalysisSet>();
371371

372-
if (Ast.BasesInternal.Length == 0) {
372+
if (Ast.Bases.Length == 0) {
373373
if (ddg.ProjectState.LanguageVersion.Is3x()) {
374374
// 3.x all classes inherit from object by default
375375
bases.Add(ddg.ProjectState.ClassInfos[BuiltinTypeId.Object]);
376376
}
377377
} else {
378378
// Process base classes
379-
for (var i = 0; i < Ast.BasesInternal.Length; i++) {
380-
var baseClassArg = Ast.BasesInternal[i];
379+
for (var i = 0; i < Ast.Bases.Length; i++) {
380+
var baseClassArg = Ast.Bases[i];
381381

382382
if (baseClassArg.Name == null) {
383383
bases.Add(EvaluateBaseClass(ddg, classInfo, i, baseClassArg.Expression));
@@ -415,33 +415,31 @@ private IAnalysisSet ProcessClassDecorators(DDG ddg, ClassInfo classInfo) {
415415
if (Ast.Decorators != null) {
416416
Expression expr = Ast.NameExpression;
417417

418-
foreach (var d in Ast.Decorators.DecoratorsInternal) {
419-
if (d != null) {
420-
var decorator = ddg._eval.Evaluate(d);
418+
foreach (var d in Ast.Decorators.Decorators.ExcludeDefault()) {
419+
var decorator = ddg._eval.Evaluate(d);
421420

422-
Expression nextExpr;
423-
if (!_decoratorCalls.TryGetValue(d, out nextExpr)) {
424-
nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) });
425-
nextExpr.SetLoc(d.IndexSpan);
426-
}
427-
expr = nextExpr;
428-
var decorated = AnalysisSet.Empty;
429-
var anyResults = false;
430-
foreach (var ns in decorator) {
431-
var fd = ns as FunctionInfo;
432-
if (fd != null && InterpreterScope.EnumerateTowardsGlobal.Any(s => s.AnalysisValue == fd)) {
433-
continue;
434-
}
435-
decorated = decorated.Union(ns.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames));
436-
anyResults = true;
421+
Expression nextExpr;
422+
if (!_decoratorCalls.TryGetValue(d, out nextExpr)) {
423+
nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) });
424+
nextExpr.SetLoc(d.IndexSpan);
425+
}
426+
expr = nextExpr;
427+
var decorated = AnalysisSet.Empty;
428+
var anyResults = false;
429+
foreach (var ns in decorator) {
430+
var fd = ns as FunctionInfo;
431+
if (fd != null && InterpreterScope.EnumerateTowardsGlobal.Any(s => s.AnalysisValue == fd)) {
432+
continue;
437433
}
434+
decorated = decorated.Union(ns.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames));
435+
anyResults = true;
436+
}
438437

439-
// If processing decorators, update the current
440-
// function type. Otherwise, we are acting as if
441-
// each decorator returns the function unmodified.
442-
if (ddg.ProjectState.Limits.ProcessCustomDecorators && anyResults) {
443-
types = decorated;
444-
}
438+
// If processing decorators, update the current
439+
// function type. Otherwise, we are acting as if
440+
// each decorator returns the function unmodified.
441+
if (ddg.ProjectState.Limits.ProcessCustomDecorators && anyResults) {
442+
types = decorated;
445443
}
446444
}
447445
}

src/Analysis/Engine/Impl/Analyzer/DDG.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ public override bool Walk(NonlocalStatement node) {
195195
public override bool Walk(ClassDefinition node) {
196196
// Evaluate decorators for references
197197
// TODO: Should apply decorators when assigning the class
198-
foreach (var d in (node.Decorators?.DecoratorsInternal).MaybeEnumerate()) {
198+
foreach (var d in (node.Decorators?.Decorators).MaybeEnumerate().ExcludeDefault()) {
199199
_eval.Evaluate(d);
200200
}
201201

src/Analysis/Engine/Impl/Analyzer/FunctionAnalysisUnit.cs

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -132,44 +132,42 @@ internal IAnalysisSet ProcessFunctionDecorators(DDG ddg) {
132132
if (Ast.Decorators != null) {
133133
Expression expr = Ast.NameExpression;
134134

135-
foreach (var d in Ast.Decorators.DecoratorsInternal) {
136-
if (d != null) {
137-
var decorator = ddg._eval.Evaluate(d);
138-
139-
if (decorator.Contains(State.ClassInfos[BuiltinTypeId.Property])) {
140-
Function.IsProperty = true;
141-
} else if (decorator.Contains(State.ClassInfos[BuiltinTypeId.StaticMethod])) {
142-
// TODO: Warn if IsClassMethod is set
143-
Function.IsStatic = true;
144-
} else if (decorator.Contains(State.ClassInfos[BuiltinTypeId.ClassMethod])) {
145-
// TODO: Warn if IsStatic is set
146-
Function.IsClassMethod = true;
147-
} else if (ProcessAbstractDecorators(decorator)) {
148-
// No-op
149-
} else {
150-
Expression nextExpr;
151-
if (!_decoratorCalls.TryGetValue(d, out nextExpr)) {
152-
nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) });
153-
nextExpr.SetLoc(d.IndexSpan);
154-
}
155-
expr = nextExpr;
156-
var decorated = AnalysisSet.Empty;
157-
var anyResults = false;
158-
foreach (var ns in decorator) {
159-
var fd = ns as FunctionInfo;
160-
if (fd != null && InterpreterScope.EnumerateTowardsGlobal.Any(s => s.AnalysisValue == fd)) {
161-
continue;
162-
}
163-
decorated = decorated.Union(ns.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames));
164-
anyResults = true;
165-
}
135+
foreach (var d in Ast.Decorators.Decorators.ExcludeDefault()) {
136+
var decorator = ddg._eval.Evaluate(d);
166137

167-
// If processing decorators, update the current
168-
// function type. Otherwise, we are acting as if
169-
// each decorator returns the function unmodified.
170-
if (ddg.ProjectState.Limits.ProcessCustomDecorators && anyResults) {
171-
types = decorated;
138+
if (decorator.Contains(State.ClassInfos[BuiltinTypeId.Property])) {
139+
Function.IsProperty = true;
140+
} else if (decorator.Contains(State.ClassInfos[BuiltinTypeId.StaticMethod])) {
141+
// TODO: Warn if IsClassMethod is set
142+
Function.IsStatic = true;
143+
} else if (decorator.Contains(State.ClassInfos[BuiltinTypeId.ClassMethod])) {
144+
// TODO: Warn if IsStatic is set
145+
Function.IsClassMethod = true;
146+
} else if (ProcessAbstractDecorators(decorator)) {
147+
// No-op
148+
} else {
149+
Expression nextExpr;
150+
if (!_decoratorCalls.TryGetValue(d, out nextExpr)) {
151+
nextExpr = _decoratorCalls[d] = new CallExpression(d, new[] { new Arg(expr) });
152+
nextExpr.SetLoc(d.IndexSpan);
153+
}
154+
expr = nextExpr;
155+
var decorated = AnalysisSet.Empty;
156+
var anyResults = false;
157+
foreach (var ns in decorator) {
158+
var fd = ns as FunctionInfo;
159+
if (fd != null && InterpreterScope.EnumerateTowardsGlobal.Any(s => s.AnalysisValue == fd)) {
160+
continue;
172161
}
162+
decorated = decorated.Union(ns.Call(expr, this, new[] { types }, ExpressionEvaluator.EmptyNames));
163+
anyResults = true;
164+
}
165+
166+
// If processing decorators, update the current
167+
// function type. Otherwise, we are acting as if
168+
// each decorator returns the function unmodified.
169+
if (ddg.ProjectState.Limits.ProcessCustomDecorators && anyResults) {
170+
types = decorated;
173171
}
174172
}
175173
}
@@ -181,8 +179,8 @@ internal IAnalysisSet ProcessFunctionDecorators(DDG ddg) {
181179
internal void AnalyzeDefaultParameters(DDG ddg) {
182180
IVariableDefinition param;
183181
var scope = (FunctionScope)Scope;
184-
for (var i = 0; i < Ast.ParametersInternal.Length; ++i) {
185-
var p = Ast.ParametersInternal[i];
182+
for (var i = 0; i < Ast.Parameters.Length; ++i) {
183+
var p = Ast.Parameters[i];
186184
if (p.Annotation != null) {
187185
var val = ddg._eval.EvaluateAnnotation(p.Annotation);
188186
if (val?.Any() == true && Scope.TryGetVariable(p.Name, out param)) {
@@ -232,7 +230,7 @@ public override string ToString() {
232230
return "{0}{1}({2})->{3}".FormatInvariant(
233231
base.ToString(),
234232
" def:",
235-
string.Join(", ", Ast.ParametersInternal.Select(p => InterpreterScope.TryGetVariable(p.Name, out var v) ? v.Types.ToString() : "{}")),
233+
string.Join(", ", Ast.Parameters.Select(p => InterpreterScope.TryGetVariable(p.Name, out var v) ? v.Types.ToString() : "{}")),
236234
((FunctionScope)Scope).ReturnValue.Types.ToString()
237235
);
238236
}

src/Analysis/Engine/Impl/Analyzer/FunctionScope.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public VariableDef GetParameter(string name) {
9494
}
9595

9696
internal void EnsureParameters(FunctionAnalysisUnit unit, bool usePlaceholders) {
97-
var astParams = Function.FunctionDefinition.ParametersInternal;
97+
var astParams = Function.FunctionDefinition.Parameters;
9898
for (int i = 0; i < astParams.Length; ++i) {
9999
var p = astParams[i];
100100
var name = p?.Name;
@@ -129,7 +129,7 @@ internal void EnsureParameters(FunctionAnalysisUnit unit, bool usePlaceholders)
129129
}
130130

131131
internal void EnsureParameterZero(FunctionAnalysisUnit unit) {
132-
var p = Function.FunctionDefinition.ParametersInternal.FirstOrDefault();
132+
var p = Function.FunctionDefinition.Parameters.FirstOrDefault();
133133
if (!string.IsNullOrEmpty(p?.Name) &&
134134
p.Kind == ParameterKind.Normal &&
135135
!unit.Function.IsStatic &&
@@ -173,7 +173,7 @@ internal bool UpdateParameters(
173173
) {
174174
EnsureParameters(unit, usePlaceholders);
175175

176-
var astParams = Function.FunctionDefinition.ParametersInternal;
176+
var astParams = Function.FunctionDefinition.Parameters;
177177
var added = false;
178178
var entry = unit.DependencyProject;
179179
var state = unit.State;

src/Analysis/Engine/Impl/Analyzer/OverviewWalker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ internal ClassInfo AddClass(ClassDefinition node, AnalysisUnit outerUnit) {
7171
var classScope = (ClassScope)unit.Scope;
7272

7373
var classVar = declScope.AddLocatedVariable(node.Name, node.NameExpression, unit);
74-
if (node.Decorators == null || node.Decorators.DecoratorsInternal.Length == 0) {
74+
if (node.Decorators == null || node.Decorators.Decorators.Length == 0) {
7575
classVar.AddTypes(unit, classScope.Class.SelfSet);
7676
}
7777

src/Analysis/Engine/Impl/ExpressionFinder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ public override bool Walk(FunctionDefinition node) {
202202
}
203203

204204
node.Decorators?.Walk(this);
205-
foreach (var p in node.ParametersInternal.MaybeEnumerate()) {
205+
foreach (var p in node.Parameters) {
206206
p?.Walk(this);
207207
}
208208
node.ReturnAnnotation?.Walk(this);
@@ -254,7 +254,7 @@ public override bool Walk(ClassDefinition node) {
254254
node.NameExpression?.Walk(this);
255255
}
256256
node.Decorators?.Walk(this);
257-
foreach (var b in node.BasesInternal.MaybeEnumerate()) {
257+
foreach (var b in node.Bases) {
258258
b.Walk(this);
259259
}
260260

src/Analysis/Engine/Impl/Infrastructure/Extensions/EnumerableExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@ public static bool SetEquals<T>(this IEnumerable<T> source, IEnumerable<T> other
5858
private static T GetKey<T, U>(KeyValuePair<T, U> keyValue) => keyValue.Key;
5959

6060
public static IEnumerable<T> Keys<T, U>(this IEnumerable<KeyValuePair<T, U>> source) => source.Select(GetKey);
61+
public static IEnumerable<T> ExcludeDefault<T>(this IEnumerable<T> source) => source.Where(i => !Equals(i, default(T)));
6162
}
6263
}

src/Analysis/Engine/Impl/Intellisense/ExtractedMethodCreator.cs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
using System;
1818
using System.Collections.Generic;
1919
using System.Diagnostics;
20+
using System.Linq;
2021
using System.Text;
22+
using Microsoft.PythonTools.Analysis.Infrastructure;
2123
using Microsoft.PythonTools.Parsing;
2224
using Microsoft.PythonTools.Parsing.Ast;
2325

@@ -58,28 +60,19 @@ public ExtractMethodResult GetExtractionResult() {
5860
bool isStaticMethod = false, isClassMethod = false;
5961
var parameters = new List<Parameter>();
6062
NameExpression selfParam = null;
61-
if (_targetScope is ClassDefinition) {
62-
var fromScope = _scopes[_scopes.Count - 1] as FunctionDefinition;
63-
Debug.Assert(fromScope != null); // we don't allow extracting from classes, so we have to be coming from a function
64-
if (fromScope != null) {
65-
if (fromScope.Decorators != null) {
66-
foreach (var decorator in fromScope.Decorators.DecoratorsInternal) {
67-
NameExpression name = decorator as NameExpression;
68-
if (name != null) {
69-
if (name.Name == "staticmethod") {
70-
isStaticMethod = true;
71-
} else if (name.Name == "classmethod") {
72-
isClassMethod = true;
73-
}
74-
}
75-
}
63+
if (_targetScope is ClassDefinition && _scopes[_scopes.Count - 1] is FunctionDefinition fromScope) {
64+
foreach (var name in (fromScope?.Decorators?.Decorators).MaybeEnumerate().ExcludeDefault().OfType<NameExpression>()) {
65+
if (name.Name == "staticmethod") {
66+
isStaticMethod = true;
67+
} else if (name.Name == "classmethod") {
68+
isClassMethod = true;
7669
}
70+
}
7771

78-
if (!isStaticMethod) {
79-
if (fromScope.ParametersInternal.Length > 0) {
80-
selfParam = fromScope.ParametersInternal[0].NameExpression;
81-
parameters.Add(new Parameter(selfParam, ParameterKind.Normal));
82-
}
72+
if (!isStaticMethod) {
73+
if (fromScope.Parameters.Length > 0) {
74+
selfParam = fromScope.Parameters[0].NameExpression;
75+
parameters.Add(new Parameter(selfParam, ParameterKind.Normal));
8376
}
8477
}
8578
}
@@ -140,7 +133,7 @@ public ExtractMethodResult GetExtractionResult() {
140133
retStmt.SetLeadingWhiteSpace(_ast, leading);
141134

142135
body = new SuiteStatement(
143-
new Statement[] {
136+
new Statement[] {
144137
body,
145138
retStmt
146139
}
@@ -159,7 +152,7 @@ public ExtractMethodResult GetExtractionResult() {
159152

160153
var res = new FunctionDefinition(new NameExpression(_name), parameters.ToArray(), body, decorators);
161154
res.IsCoroutine = isCoroutine;
162-
155+
163156
StringBuilder newCall = new StringBuilder();
164157
newCall.Append(_target.IndentationLevel);
165158
var method = res.ToCodeString(_ast);
@@ -235,15 +228,12 @@ public ExtractMethodResult GetExtractionResult() {
235228
newCall.Append("await ");
236229
}
237230

238-
if (_targetScope is ClassDefinition) {
239-
var fromScope = _scopes[_scopes.Count - 1] as FunctionDefinition;
240-
Debug.Assert(fromScope != null); // we don't allow extracting from classes, so we have to be coming from a function
241-
231+
if (_targetScope is ClassDefinition && _scopes[_scopes.Count - 1] is FunctionDefinition fromScope2) {
242232
if (isStaticMethod) {
243233
newCall.Append(_targetScope.Name);
244234
newCall.Append('.');
245-
} else if (fromScope != null && fromScope.ParametersInternal.Length > 0) {
246-
newCall.Append(fromScope.ParametersInternal[0].Name);
235+
} else if (fromScope2 != null && fromScope2.Parameters.Length > 0) {
236+
newCall.Append(fromScope2.Parameters[0].Name);
247237
newCall.Append('.');
248238
}
249239
}

src/Analysis/Engine/Impl/Intellisense/FlowChecker.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ public override bool Walk(ClassDefinition node) {
296296
} else {
297297
// analyze the class definition itself (it is visited while analyzing parent scope):
298298
Define(node.Name);
299-
foreach (var e in node.BasesInternal) {
299+
foreach (var e in node.Bases) {
300300
e.Expression.Walk(this);
301301
}
302302
return false;
@@ -365,14 +365,14 @@ public override bool Walk(FromImportStatement node) {
365365
public override bool Walk(FunctionDefinition node) {
366366
if (node == _scope) {
367367
// the function body is being analyzed, go deep:
368-
foreach (Parameter p in node.ParametersInternal) {
368+
foreach (Parameter p in node.Parameters) {
369369
p.Walk(_fdef);
370370
}
371371
return true;
372372
} else {
373373
// analyze the function definition itself (it is visited while analyzing parent scope):
374374
Define(node.Name);
375-
foreach (Parameter p in node.ParametersInternal) {
375+
foreach (Parameter p in node.Parameters) {
376376
if (p.DefaultValue != null) {
377377
p.DefaultValue.Walk(this);
378378
}

0 commit comments

Comments
 (0)