Skip to content

Commit 74ad470

Browse files
authored
Merge pull request #1859 from Hosch250/Issue1851
Hard-code a few missing declarations
2 parents 2414e80 + acee813 commit 74ad470

13 files changed

+260
-52
lines changed

RetailCoder.VBE/API/ParserState.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.ComponentModel;
34
using System.Linq;
45
using System.Runtime.InteropServices;
@@ -8,6 +9,7 @@
89
using Rubberduck.UI.Command.MenuItems;
910
using Rubberduck.Parsing.Preprocessing;
1011
using System.Globalization;
12+
using Rubberduck.Parsing.Symbols;
1113

1214
namespace Rubberduck.API
1315
{
@@ -65,7 +67,8 @@ public void Initialize(VBE vbe)
6567
}
6668
Func<IVBAPreprocessor> preprocessorFactory = () => new VBAPreprocessor(double.Parse(vbe.Version, CultureInfo.InvariantCulture));
6769
_attributeParser = new AttributeParser(new ModuleExporter(), preprocessorFactory);
68-
_parser = new RubberduckParser(vbe, _state, _attributeParser, preprocessorFactory);
70+
_parser = new RubberduckParser(vbe, _state, _attributeParser, preprocessorFactory,
71+
new List<ICustomDeclarationLoader> { new DebugDeclarations(_state), new FormEventDeclarations(_state) });
6972
}
7073

7174
/// <summary>

RetailCoder.VBE/Common/DeclarationExtensions.cs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using Rubberduck.Parsing;
99
using Rubberduck.Parsing.Grammar;
1010
using Rubberduck.Parsing.Symbols;
11+
using Rubberduck.Parsing.VBA;
1112
using Rubberduck.Properties;
1213
using Rubberduck.UI;
1314
using Rubberduck.VBEditor;
@@ -330,9 +331,9 @@ public static Declaration FindSelectedDeclaration(this IEnumerable<Declaration>
330331
return declaration;
331332
}
332333

333-
public static IEnumerable<Declaration> FindFormEventHandlers(this IEnumerable<Declaration> declarations)
334+
public static IEnumerable<Declaration> FindFormEventHandlers(this RubberduckParserState state)
334335
{
335-
var items = declarations.ToList();
336+
var items = state.AllDeclarations.ToList();
336337

337338
var forms = items.Where(item => item.DeclarationType == DeclarationType.ClassModule
338339
&& item.QualifiedName.QualifiedModuleName.Component != null
@@ -342,18 +343,24 @@ public static IEnumerable<Declaration> FindFormEventHandlers(this IEnumerable<De
342343
var result = new List<Declaration>();
343344
foreach (var declaration in forms)
344345
{
345-
result.AddRange(FindFormEventHandlers(items, declaration));
346+
result.AddRange(FindFormEventHandlers(state, declaration));
346347
}
347348

348349
return result;
349350
}
350351

351-
public static IEnumerable<Declaration> FindFormEventHandlers(this IEnumerable<Declaration> declarations, Declaration userForm)
352+
public static IEnumerable<Declaration> FindFormEventHandlers(this RubberduckParserState state, Declaration userForm)
352353
{
353-
var items = declarations as IList<Declaration> ?? declarations.ToList();
354+
var items = state.AllDeclarations.ToList();
354355
var events = items.Where(item => item.IsBuiltIn
355-
&& item.ParentScope == "MSForms.UserForm"
356+
&& item.ParentScope == "FM20.DLL;MSForms.FormEvents"
356357
&& item.DeclarationType == DeclarationType.Event).ToList();
358+
359+
var e = items.Where(item => item.DeclarationType == DeclarationType.Event).ToList();
360+
var e1 = items.Where(item => item.DeclarationType == DeclarationType.Event && item.IdentifierName == "QueryClose").ToList();
361+
362+
var s = items.Where(item => item.IdentifierName.Contains("QueryClose") || item.IdentifierName.Contains("Initialize") || item.IdentifierName.Contains("Activate")).ToList();
363+
357364
var handlerNames = events.Select(item => "UserForm_" + item.IdentifierName);
358365
var handlers = items.Where(item => item.ParentScope == userForm.Scope
359366
&& item.DeclarationType == DeclarationType.Procedure

RetailCoder.VBE/Inspections/ParameterCanBeByValInspection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
4444
.Concat(declarations.FindInterfaceImplementationMembers())
4545
.ToList();
4646

47-
var formEventHandlerScopes = declarations.FindFormEventHandlers()
47+
var formEventHandlerScopes = State.FindFormEventHandlers()
4848
.Select(handler => handler.Scope);
4949

5050
var eventScopes = declarations.Where(item =>

RetailCoder.VBE/Inspections/ProcedureNotUsedInspection.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
2424
{
2525
var declarations = UserDeclarations.ToList();
2626

27-
var classes = declarations.Where(item => item.DeclarationType == DeclarationType.ClassModule).ToList();
28-
var modules = declarations.Where(item => item.DeclarationType == DeclarationType.ProceduralModule).ToList();
27+
var classes = UserDeclarations.Where(item => item.DeclarationType == DeclarationType.ClassModule).ToList();
28+
var modules = UserDeclarations.Where(item => item.DeclarationType == DeclarationType.ProceduralModule).ToList();
2929

3030
var handlers = declarations.Where(item => item.DeclarationType == DeclarationType.Control)
3131
.SelectMany(control => declarations.FindEventHandlers(control)).ToList();
3232

33-
var withEventFields = declarations.Where(item => item.DeclarationType == DeclarationType.Variable && item.IsWithEvents);
33+
var withEventFields = UserDeclarations.Where(item => item.DeclarationType == DeclarationType.Variable && item.IsWithEvents);
3434
handlers.AddRange(withEventFields.SelectMany(field => declarations.FindEventProcedures(field)));
3535

3636
var forms = declarations.Where(item => item.DeclarationType == DeclarationType.ClassModule
@@ -39,7 +39,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
3939

4040
if (forms.Any())
4141
{
42-
handlers.AddRange(forms.SelectMany(form => declarations.FindFormEventHandlers(form)));
42+
handlers.AddRange(forms.SelectMany(form => State.FindFormEventHandlers(form)));
4343
}
4444

4545
handlers.AddRange(State.AllDeclarations.FindBuiltInEventHandlers());

RetailCoder.VBE/Root/RubberduckModule.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
using NLog;
3535
using Rubberduck.Parsing.Preprocessing;
3636
using System.Globalization;
37+
using Rubberduck.Parsing.Symbols;
3738

3839
namespace Rubberduck.Root
3940
{
@@ -94,7 +95,7 @@ public override void Load()
9495
Rebind<IIndenterSettings>().To<IndenterSettings>();
9596
Bind<Func<IIndenterSettings>>().ToMethod(t => () => _kernel.Get<IGeneralConfigService>().LoadConfiguration().UserSettings.IndenterSettings);
9697

97-
//Bind<TestExplorerModel>().To<StandardModuleTestExplorerModel>().InSingletonScope();
98+
BindCustomDeclarationLoadersToParser();
9899
Rebind<IRubberduckParser>().To<RubberduckParser>().InSingletonScope();
99100
Bind<Func<IVBAPreprocessor>>().ToMethod(p => () => new VBAPreprocessor(double.Parse(_vbe.Version, CultureInfo.InvariantCulture)));
100101

@@ -356,6 +357,18 @@ private void BindCommandsToCodeExplorer()
356357
}
357358
}
358359

360+
private void BindCustomDeclarationLoadersToParser()
361+
{
362+
var loaders = Assembly.GetAssembly(typeof(ICustomDeclarationLoader))
363+
.GetTypes()
364+
.Where(type => type.GetInterfaces().Contains(typeof(ICustomDeclarationLoader)));
365+
366+
foreach (var loader in loaders)
367+
{
368+
_kernel.Bind<ICustomDeclarationLoader>().To(loader).InSingletonScope();
369+
}
370+
}
371+
359372
private IEnumerable<IMenuItem> GetRubberduckMenuItems()
360373
{
361374
return new[]

Rubberduck.Parsing/Rubberduck.Parsing.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@
132132
<Compile Include="Symbols\ComInformation.cs" />
133133
<Compile Include="Symbols\CommentNode.cs" />
134134
<Compile Include="Symbols\ComParameter.cs" />
135-
<Compile Include="Symbols\CustomDeclarations.cs" />
135+
<Compile Include="Symbols\DebugDeclarations.cs" />
136+
<Compile Include="Symbols\FormEventDeclarations.cs" />
137+
<Compile Include="Symbols\ICustomDelarationLoader.cs" />
136138
<Compile Include="Symbols\Identifier.cs" />
137139
<Compile Include="Binding\IBindingContext.cs" />
138140
<Compile Include="Binding\IBoundExpression.cs" />

Rubberduck.Parsing/Symbols/CustomDeclarations.cs renamed to Rubberduck.Parsing/Symbols/DebugDeclarations.cs

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,47 @@
44
using Rubberduck.VBEditor;
55
using System.Collections.Generic;
66
using System.Diagnostics;
7+
using Rubberduck.Parsing.Grammar;
78

89
namespace Rubberduck.Parsing.Symbols
910
{
10-
public static class CustomDeclarations
11+
public class DebugDeclarations : ICustomDeclarationLoader
1112
{
12-
public static Declaration DEBUG_PRINT;
13-
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
13+
public static Declaration DebugPrint;
14+
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
15+
private readonly DeclarationFinder _finder;
1416

15-
public static IReadOnlyList<Declaration> Load(Declaration parentProject, Declaration parentModule)
17+
public DebugDeclarations(RubberduckParserState state)
18+
{
19+
_finder = new DeclarationFinder(state.AllDeclarations, new CommentNode[] { }, new IAnnotation[] { });
20+
}
21+
22+
public IReadOnlyList<Declaration> Load()
23+
{
24+
foreach (var item in _finder.MatchName(Tokens.Err))
25+
{
26+
if (item.IsBuiltIn && item.DeclarationType == DeclarationType.Variable &&
27+
item.Accessibility == Accessibility.Global)
28+
{
29+
return new List<Declaration>();
30+
}
31+
}
32+
33+
var vba = _finder.FindProject("VBA");
34+
if (vba == null)
35+
{
36+
// if VBA project is null, we haven't loaded any COM references;
37+
// we're in a unit test and mock project didn't setup any references.
38+
return new List<Declaration>();
39+
}
40+
41+
var informationModule = _finder.FindStdModule("Information", vba, true);
42+
Debug.Assert(informationModule != null, "We expect the information module to exist in the VBA project.");
43+
44+
return Load(vba, informationModule);
45+
}
46+
47+
private IReadOnlyList<Declaration> Load(Declaration parentProject, Declaration parentModule)
1648
{
1749
_logger.Debug("Loading custom declarations with {0} as parent project and {1} as parent module.", parentProject.IdentifierName, parentModule.IdentifierName);
1850
List<Declaration> declarations = new List<Declaration>();
@@ -28,16 +60,16 @@ public static IReadOnlyList<Declaration> Load(Declaration parentProject, Declara
2860
declarations.Add(debugObject);
2961
declarations.Add(debugAssert);
3062
declarations.Add(debugPrint);
31-
declarations.AddRange(AddSpecialFormDeclarations(parentProject, parentModule));
63+
declarations.AddRange(AddSpecialFormDeclarations(parentModule));
3264
// Debug.Print has the same special syntax as the print and write statement.
3365
// Because of that it is treated specially in the grammar and normally wouldn't be resolved.
3466
// Since we still want it to be resolved we make it easier for the resolver to access the debug print
3567
// declaration by exposing it in this way.
36-
DEBUG_PRINT = debugPrint;
68+
DebugPrint = debugPrint;
3769
return declarations;
3870
}
3971

40-
private static List<Declaration> AddSpecialFormDeclarations(Declaration parentProject, Declaration parentModule)
72+
private List<Declaration> AddSpecialFormDeclarations(Declaration parentModule)
4173
{
4274
List<Declaration> declarations = new List<Declaration>();
4375
Debug.Assert(parentModule != null);
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
using System.Collections.Generic;
2+
using NLog;
3+
using Rubberduck.Parsing.VBA;
4+
using Rubberduck.VBEditor;
5+
6+
namespace Rubberduck.Parsing.Symbols
7+
{
8+
public class FormEventDeclarations : ICustomDeclarationLoader
9+
{
10+
private readonly RubberduckParserState _state;
11+
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
12+
13+
public FormEventDeclarations(RubberduckParserState state)
14+
{
15+
_state = state;
16+
}
17+
18+
public IReadOnlyList<Declaration> Load()
19+
{
20+
Declaration formsClassModule = null;
21+
foreach (var declaration in _state.AllDeclarations)
22+
{
23+
if (declaration.DeclarationType == DeclarationType.ClassModule &&
24+
declaration.Scope == "FM20.DLL;MSForms.FormEvents")
25+
{
26+
formsClassModule = declaration;
27+
}
28+
}
29+
30+
return AddHiddenMSFormDeclarations(formsClassModule);
31+
}
32+
33+
private IReadOnlyList<Declaration> AddHiddenMSFormDeclarations(Declaration parentModule)
34+
{
35+
var userFormActivateEvent = new Declaration(
36+
new QualifiedMemberName(
37+
new QualifiedModuleName("MSForms", "C:\\WINDOWS\\system32\\FM20.DLL", "FormEvents"), "Activate"),
38+
parentModule,
39+
"FM20.DLL;MSForms.FormEvents",
40+
string.Empty,
41+
string.Empty,
42+
false,
43+
false,
44+
Accessibility.Global,
45+
DeclarationType.Event,
46+
false,
47+
null);
48+
49+
var userFormDeactivateEvent = new Declaration(
50+
new QualifiedMemberName(
51+
new QualifiedModuleName("MSForms", "C:\\WINDOWS\\system32\\FM20.DLL", "FormEvents"), "Deactivate"),
52+
parentModule,
53+
"FM20.DLL;MSForms.FormEvents",
54+
string.Empty,
55+
string.Empty,
56+
false,
57+
false,
58+
Accessibility.Global,
59+
DeclarationType.Event,
60+
false,
61+
null);
62+
63+
var userFormInitializeEvent = new Declaration(
64+
new QualifiedMemberName(
65+
new QualifiedModuleName("MSForms", "C:\\WINDOWS\\system32\\FM20.DLL", "FormEvents"), "Initialize"),
66+
parentModule,
67+
"FM20.DLL;MSForms.FormEvents",
68+
string.Empty,
69+
string.Empty,
70+
false,
71+
false,
72+
Accessibility.Global,
73+
DeclarationType.Event,
74+
false,
75+
null);
76+
77+
var userFormQueryCloseEvent = new Declaration(
78+
new QualifiedMemberName(
79+
new QualifiedModuleName("MSForms", "C:\\WINDOWS\\system32\\FM20.DLL", "FormEvents"), "QueryClose"),
80+
parentModule,
81+
"FM20.DLL;MSForms.FormEvents",
82+
string.Empty,
83+
string.Empty,
84+
false,
85+
false,
86+
Accessibility.Global,
87+
DeclarationType.Event,
88+
false,
89+
null);
90+
91+
var userFormQueryCloseEventCancelParameter = new ParameterDeclaration(
92+
new QualifiedMemberName(
93+
new QualifiedModuleName("MSForms", "C:\\WINDOWS\\system32\\FM20.DLL", "FormEvents"), "Cancel"),
94+
userFormQueryCloseEvent,
95+
null,
96+
new Selection(),
97+
"Integer",
98+
null,
99+
string.Empty,
100+
false,
101+
false);
102+
103+
var userFormQueryCloseEventCloseModeParameter = new ParameterDeclaration(
104+
new QualifiedMemberName(
105+
new QualifiedModuleName("MSForms", "C:\\WINDOWS\\system32\\FM20.DLL", "FormEvents"), "CloseMode"),
106+
userFormQueryCloseEvent,
107+
null,
108+
new Selection(),
109+
"Integer",
110+
null,
111+
string.Empty,
112+
false,
113+
false);
114+
115+
var userFormResizeEvent = new Declaration(
116+
new QualifiedMemberName(
117+
new QualifiedModuleName("MSForms", "C:\\WINDOWS\\system32\\FM20.DLL", "FormEvents"), "Resize"),
118+
parentModule,
119+
"FM20.DLL;MSForms.FormEvents",
120+
string.Empty,
121+
string.Empty,
122+
false,
123+
false,
124+
Accessibility.Global,
125+
DeclarationType.Event,
126+
false,
127+
null);
128+
129+
var userFormTerminateEvent = new Declaration(
130+
new QualifiedMemberName(
131+
new QualifiedModuleName("MSForms", "C:\\WINDOWS\\system32\\FM20.DLL", "FormEvents"), "Terminate"),
132+
parentModule,
133+
"FM20.DLL;MSForms.FormEvents",
134+
string.Empty,
135+
string.Empty,
136+
false,
137+
false,
138+
Accessibility.Global,
139+
DeclarationType.Event,
140+
false,
141+
null);
142+
143+
return new List<Declaration>
144+
{
145+
userFormActivateEvent,
146+
userFormDeactivateEvent,
147+
userFormInitializeEvent,
148+
userFormQueryCloseEvent,
149+
userFormQueryCloseEventCancelParameter,
150+
userFormQueryCloseEventCloseModeParameter,
151+
userFormResizeEvent,
152+
userFormTerminateEvent
153+
};
154+
}
155+
}
156+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System.Collections.Generic;
2+
3+
namespace Rubberduck.Parsing.Symbols
4+
{
5+
public interface ICustomDeclarationLoader
6+
{
7+
IReadOnlyList<Declaration> Load();
8+
}
9+
}

0 commit comments

Comments
 (0)