@@ -113,7 +113,7 @@ private static IAnalysisSet ResolveAndAdd(AnalysisUnit unit, IAnalysisSet set, A
113113 return set . Union ( value . Resolve ( unit ) ) ;
114114 }
115115
116- internal IEnumerable < AnalysisVariable > ToVariables ( IReferenceable referenceable ) {
116+ internal static IEnumerable < AnalysisVariable > ToVariables ( IReferenceable referenceable ) {
117117 var def = referenceable as VariableDef ;
118118
119119 if ( def != null ) {
@@ -210,10 +210,22 @@ public VariablesResult GetVariables(Expression expr, SourceLocation location, st
210210
211211 var unit = GetNearestEnclosingAnalysisUnit ( scope ) ;
212212 var tree = unit . Tree ;
213-
214213 var eval = new ExpressionEvaluator ( unit . CopyForEval ( ) , scope , mergeScopes : true ) ;
215- var variables = Enumerable . Empty < IAnalysisVariable > ( ) ;
216214
215+ var result = GetVariablesFromCallExpression ( unit , eval , scope , location , originalText ) ;
216+ if ( result != null ) {
217+ return result ;
218+ }
219+
220+ result = GetVariablesFromNameExpression ( expr , unit , scope ) ;
221+ if ( result != null ) {
222+ return result ;
223+ }
224+
225+ return GetVariablesFromMemberExpression ( expr , unit , eval ) ;
226+ }
227+
228+ private static VariablesResult GetVariablesFromCallExpression ( AnalysisUnit unit , ExpressionEvaluator eval , IScope scope , SourceLocation location , string originalText ) {
217229 var finder = new ExpressionFinder ( unit . Tree , new GetExpressionOptions { Calls = true } ) ;
218230 var callNode = finder . GetExpression ( location ) as CallExpression ;
219231 if ( callNode != null ) {
@@ -231,42 +243,52 @@ public VariablesResult GetVariables(Expression expr, SourceLocation location, st
231243 unit . Tree ) ;
232244 }
233245 }
246+ return null ;
247+ }
234248
235- if ( expr is NameExpression name ) {
236- if ( ! scope . EnumerateTowardsGlobal . Any ( ) ) {
237- variables = _unit . State . BuiltinModule . GetDefinitions ( name . Name ) . SelectMany ( ToVariables ) ;
238- } else {
239- foreach ( var s in scope . EnumerateTowardsGlobal ) {
240- var scopeVariables = GetVariablesInScope ( name , s ) . Distinct ( ) ;
241- variables = variables . Union ( scopeVariables ) ;
242- var args = scopeVariables . Where ( v => IsFunctionArgument ( s , v ) ) ;
243- if ( args . Any ( ) ) {
244- break ;
245- }
246- }
249+ private VariablesResult GetVariablesFromNameExpression ( Expression expr , AnalysisUnit unit , IScope scope ) {
250+ if ( ! ( expr is NameExpression name ) ) {
251+ return null ;
252+ }
247253
248- // Now take outermost definition and treat inner ones (such as reassignments) as references
249- var others = variables . Where ( v => v . Type == VariableType . Reference || v . Type == VariableType . Value ) ;
250- var definitions = variables
251- . Where ( v => v . Type == VariableType . Definition )
252- . OrderBy ( v => v . Location . Span . Start )
253- . ToArray ( ) ;
254+ var variables = Enumerable . Empty < IAnalysisVariable > ( ) ;
255+ if ( ! scope . EnumerateTowardsGlobal . Any ( ) ) {
256+ variables = _unit . State . BuiltinModule . GetDefinitions ( name . Name ) . SelectMany ( ToVariables ) ;
257+ return new VariablesResult ( variables , unit . Tree ) ;
258+ }
254259
255- if ( definitions . Length > 0 ) {
256- var defsToRefs = definitions . Skip ( 1 ) . Select ( v => new AnalysisVariable ( v . Variable , VariableType . Reference , v . Location ) ) ;
257- variables = definitions . Take ( 1 ) . Concat ( others . Concat ( defsToRefs ) ) ;
258- }
260+ foreach ( var s in scope . EnumerateTowardsGlobal ) {
261+ var scopeVariables = GetVariablesInScope ( name , s ) . Distinct ( ) ;
262+ variables = variables . Union ( scopeVariables ) ;
263+ var args = scopeVariables . Where ( v => IsFunctionArgument ( s , v ) ) ;
264+ if ( args . Any ( ) ) {
265+ break ;
259266 }
260- return new VariablesResult ( variables , unit . Tree ) ;
261267 }
262268
269+ // Now take outermost definition and treat inner ones (such as reassignments) as references
270+ var others = variables . Where ( v => v . Type == VariableType . Reference || v . Type == VariableType . Value ) ;
271+ var definitions = variables
272+ . Where ( v => v . Type == VariableType . Definition )
273+ . OrderBy ( v => v . Location . Span . Start )
274+ . ToArray ( ) ;
275+
276+ if ( definitions . Length > 0 ) {
277+ var defsToRefs = definitions . Skip ( 1 ) . Select ( v => new AnalysisVariable ( v . Variable , VariableType . Reference , v . Location ) ) ;
278+ variables = definitions . Take ( 1 ) . Concat ( others . Concat ( defsToRefs ) ) ;
279+ }
280+
281+ return new VariablesResult ( variables , unit . Tree ) ;
282+ }
283+
284+ private VariablesResult GetVariablesFromMemberExpression ( Expression expr , AnalysisUnit unit , ExpressionEvaluator eval ) {
285+ var variables = Enumerable . Empty < IAnalysisVariable > ( ) ;
263286 if ( expr is MemberExpression member && ! string . IsNullOrEmpty ( member . Name ) ) {
264287 var objects = eval . Evaluate ( member . Target ) ;
265288 foreach ( var v in objects . OfType < IReferenceableContainer > ( ) ) {
266289 variables = variables . Union ( v . GetDefinitions ( member . Name ) . SelectMany ( ToVariables ) ) ;
267290 }
268291 }
269-
270292 return new VariablesResult ( variables , unit . Tree ) ;
271293 }
272294
@@ -282,7 +304,7 @@ private bool IsFunctionArgument(IScope scope, IAnalysisVariable v) {
282304 return false ;
283305 }
284306
285- private IEnumerable < IAnalysisVariable > GetVariablesInScope ( NameExpression name , IScope scope ) {
307+ private static IEnumerable < IAnalysisVariable > GetVariablesInScope ( NameExpression name , IScope scope ) {
286308 var result = new List < IAnalysisVariable > ( ) ;
287309
288310 result . AddRange ( scope . GetMergedVariables ( name . Name ) . SelectMany ( ToVariables ) ) ;
0 commit comments