Skip to content

Commit

Permalink
Merge pull request #4098 from mansellan/4097
Browse files Browse the repository at this point in the history
VB6 - Do not delete source files during attributes parse
  • Loading branch information
retailcoder committed Jun 21, 2018
2 parents 6bd9088 + 49b04cf commit 3489486
Show file tree
Hide file tree
Showing 25 changed files with 169 additions and 119 deletions.
6 changes: 3 additions & 3 deletions Rubberduck.API/VBA/Parser.cs
Expand Up @@ -87,10 +87,10 @@ internal Parser(object vbe) : this()
_state = new RubberduckParserState(_vbe, projectRepository, declarationFinderFactory, _vbeEvents);
_state.StateChanged += _state_StateChanged;

var exporter = new ModuleExporter();
var sourceCodeHandler = _vbe.SourceCodeHandler;

IVBAPreprocessor preprocessorFactory() => new VBAPreprocessor(double.Parse(_vbe.Version, CultureInfo.InvariantCulture));
_attributeParser = new AttributeParser(exporter, preprocessorFactory, _state.ProjectsProvider);
_attributeParser = new AttributeParser(sourceCodeHandler, preprocessorFactory, _state.ProjectsProvider);
var projectManager = new RepositoryProjectManager(projectRepository);
var moduleToModuleReferenceManager = new ModuleToModuleReferenceManager();
var parserStateManager = new ParserStateManager(_state);
Expand All @@ -113,7 +113,7 @@ internal Parser(object vbe) : this()
parserStateManager,
preprocessorFactory,
_attributeParser,
exporter);
sourceCodeHandler);
var declarationResolveRunner = new DeclarationResolveRunner(
_state,
parserStateManager,
Expand Down
1 change: 1 addition & 0 deletions Rubberduck.Core/App.cs
Expand Up @@ -10,6 +10,7 @@
using System.Diagnostics;
using System.Globalization;
using Rubberduck.Parsing.UIContext;
using Rubberduck.Resources;
using Rubberduck.UI.Command;
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
using Rubberduck.VBEditor.Utility;
Expand Down
23 changes: 0 additions & 23 deletions Rubberduck.Core/Common/ModuleExporter.cs

This file was deleted.

2 changes: 0 additions & 2 deletions Rubberduck.Core/Rubberduck.Core.csproj
Expand Up @@ -312,7 +312,6 @@
<Compile Include="CodeAnalysis\CodeMetrics\CodeMetricsViewModel.cs" />
<Compile Include="CodeAnalysis\CodeMetrics\ICodeMetricResult.cs" />
<Compile Include="CodeAnalysis\CodeMetrics\ICodeMetricsParseTreeListener.cs" />
<Compile Include="Common\ApplicationConstants.cs" />
<Compile Include="Common\DeclarationIconCache.cs" />
<Compile Include="Common\ExportFormatter.cs" />
<Compile Include="Common\ClipboardWriter.cs" />
Expand All @@ -326,7 +325,6 @@
<Compile Include="Common\IOperatingSystem.cs" />
<Compile Include="Common\IRubberduckHooks.cs" />
<Compile Include="Common\LogLevelHelper.cs" />
<Compile Include="Common\ModuleExporter.cs" />
<Compile Include="Common\StringExtensions.cs" />
<Compile Include="Common\VariableNameValidator.cs" />
<Compile Include="Common\WinAPI\RegistryAccess.cs" />
Expand Down
23 changes: 7 additions & 16 deletions Rubberduck.Parsing/Rewriter/MemberAttributesRewriter.cs
@@ -1,6 +1,7 @@
using System.IO;
using Antlr4.Runtime;
using Rubberduck.Parsing.VBA;
using Rubberduck.VBEditor;
using Rubberduck.VBEditor.SafeComWrappers;
using Rubberduck.VBEditor.SafeComWrappers.Abstract;

Expand All @@ -19,41 +20,31 @@ namespace Rubberduck.Parsing.Rewriter
/// </remarks>
public class MemberAttributesRewriter : ModuleRewriter
{
private readonly IModuleExporter _exporter;
private readonly ISourceCodeHandler _sourceCodeHandler;

public MemberAttributesRewriter(IModuleExporter exporter, ICodeModule module, TokenStreamRewriter rewriter)
public MemberAttributesRewriter(ISourceCodeHandler sourceCodeHandler, ICodeModule module, TokenStreamRewriter rewriter)
: base(module, rewriter)
{
_exporter = exporter;
_sourceCodeHandler = sourceCodeHandler;
}

public override void Rewrite()
{
if(!IsDirty) { return; }

var component = Module.Parent;
var vbeKind = component.VBE.Kind;
if (component.Type == ComponentType.Document)
{
// can't re-import a document module
return;
}

var file = vbeKind == VBEKind.Embedded
? _exporter.Export(component)
: component.GetFileName(1);
var file = _sourceCodeHandler.Export(component);

var content = Rewriter.GetText();
File.WriteAllText(file, content);

if (vbeKind == VBEKind.Standalone)
{
return;
}

var components = component.Collection;
components.Remove(component);
components.ImportSourceFile(file);

_sourceCodeHandler.Import(component, file);
}
}
}
1 change: 0 additions & 1 deletion Rubberduck.Parsing/Rubberduck.Parsing.csproj
Expand Up @@ -394,7 +394,6 @@
<Compile Include="VBA\ComponentParseTask.cs" />
<Compile Include="VBA\EnumerableExtensions.cs" />
<Compile Include="VBA\IAttributeParser.cs" />
<Compile Include="VBA\IModuleExporter.cs" />
<Compile Include="VBA\IModuleToModuleReferenceManager.cs" />
<Compile Include="VBA\IDeclarationResolveRunner.cs" />
<Compile Include="VBA\ICOMReferenceSynchronizer.cs" />
Expand Down
34 changes: 6 additions & 28 deletions Rubberduck.Parsing/VBA/AttributeParser.cs
Expand Up @@ -2,6 +2,7 @@
using Antlr4.Runtime.Tree;
using Rubberduck.Parsing.Symbols;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
Expand All @@ -16,13 +17,13 @@ namespace Rubberduck.Parsing.VBA
{
public class AttributeParser : IAttributeParser
{
private readonly IModuleExporter _exporter;
private readonly ISourceCodeHandler _sourceCodeHandler;
private readonly Func<IVBAPreprocessor> _preprocessorFactory;
private readonly IProjectsProvider _projectsProvider;

public AttributeParser(IModuleExporter exporter, Func<IVBAPreprocessor> preprocessorFactory, IProjectsProvider projectsProvider)
public AttributeParser(ISourceCodeHandler sourceCodeHandler, Func<IVBAPreprocessor> preprocessorFactory, IProjectsProvider projectsProvider)
{
_exporter = exporter;
_sourceCodeHandler = sourceCodeHandler;
_preprocessorFactory = preprocessorFactory;
_projectsProvider = projectsProvider;
}
Expand All @@ -37,35 +38,12 @@ public AttributeParser(IModuleExporter exporter, Func<IVBAPreprocessor> preproce
cancellationToken.ThrowIfCancellationRequested();
var component = _projectsProvider.Component(module);

var path = component.VBE.Kind == VBEKind.Embedded
? _exporter.Export(component)
: component.GetFileName(1);

if (!File.Exists(path))
var code = _sourceCodeHandler.Read(component);
if (code == null)
{
// a document component without any code wouldn't be exported (file would be empty anyway).
return (null, null, new Dictionary<Tuple<string, DeclarationType>, Attributes>());
}

string code;
if (module.ComponentType == ComponentType.Document)
{
code = File.ReadAllText(path, Encoding.UTF8); //We export the code from Documents as UTF8.
}
else
{
code = File.ReadAllText(path, Encoding.Default); //The VBE exports encoded in the current ANSI codepage from the windows settings.
}

try
{
File.Delete(path);
}
catch
{
// Meh.
}

cancellationToken.ThrowIfCancellationRequested();

var type = module.ComponentType == ComponentType.StandardModule
Expand Down
8 changes: 4 additions & 4 deletions Rubberduck.Parsing/VBA/ComponentParseTask.cs
Expand Up @@ -25,7 +25,7 @@ class ComponentParseTask
private readonly QualifiedModuleName _module;
private readonly TokenStreamRewriter _rewriter;
private readonly IAttributeParser _attributeParser;
private readonly IModuleExporter _exporter;
private readonly ISourceCodeHandler _sourceCodeHandler;
private readonly IVBAPreprocessor _preprocessor;
private readonly VBAModuleParser _parser;
private readonly IProjectsProvider _projectsProvider;
Expand All @@ -36,12 +36,12 @@ class ComponentParseTask

private readonly Guid _taskId;

public ComponentParseTask(QualifiedModuleName module, IVBAPreprocessor preprocessor, IAttributeParser attributeParser, IModuleExporter exporter, IProjectsProvider projectsProvider, TokenStreamRewriter rewriter = null)
public ComponentParseTask(QualifiedModuleName module, IVBAPreprocessor preprocessor, IAttributeParser attributeParser, ISourceCodeHandler sourceCodeHandler, IProjectsProvider projectsProvider, TokenStreamRewriter rewriter = null)
{
_taskId = Guid.NewGuid();

_attributeParser = attributeParser;
_exporter = exporter;
_sourceCodeHandler = sourceCodeHandler;
_preprocessor = preprocessor;
_module = module;
_rewriter = rewriter;
Expand Down Expand Up @@ -72,7 +72,7 @@ public void Start(CancellationToken cancellationToken)
cancellationToken.ThrowIfCancellationRequested();

var attributesPassParseResults = RunAttributesPass(cancellationToken);
var rewriter = new MemberAttributesRewriter(_exporter, _projectsProvider.Component(_module).CodeModule, new TokenStreamRewriter(attributesPassParseResults.tokenStream ?? tokenStream));
var rewriter = new MemberAttributesRewriter(_sourceCodeHandler, _projectsProvider.Component(_module).CodeModule, new TokenStreamRewriter(attributesPassParseResults.tokenStream ?? tokenStream));

var completedHandler = ParseCompleted;
if (completedHandler != null && !cancellationToken.IsCancellationRequested)
Expand Down
18 changes: 0 additions & 18 deletions Rubberduck.Parsing/VBA/IModuleExporter.cs

This file was deleted.

4 changes: 2 additions & 2 deletions Rubberduck.Parsing/VBA/ParseRunner.cs
Expand Up @@ -17,12 +17,12 @@ public class ParseRunner : ParseRunnerBase
IParserStateManager parserStateManager,
Func<IVBAPreprocessor> preprocessorFactory,
IAttributeParser attributeParser,
IModuleExporter exporter)
ISourceCodeHandler sourceCodeHandler)
:base(state,
parserStateManager,
preprocessorFactory,
attributeParser,
exporter)
sourceCodeHandler)
{ }

public override void ParseModules(IReadOnlyCollection<QualifiedModuleName> modules, CancellationToken token)
Expand Down
8 changes: 4 additions & 4 deletions Rubberduck.Parsing/VBA/ParseRunnerBase.cs
Expand Up @@ -18,14 +18,14 @@ public abstract class ParseRunnerBase : IParseRunner
private readonly RubberduckParserState _state;
private readonly Func<IVBAPreprocessor> _preprocessorFactory;
private readonly IAttributeParser _attributeParser;
private readonly IModuleExporter _exporter;
private readonly ISourceCodeHandler _sourceCodeHandler;

protected ParseRunnerBase(
RubberduckParserState state,
IParserStateManager parserStateManager,
Func<IVBAPreprocessor> preprocessorFactory,
IAttributeParser attributeParser,
IModuleExporter exporter)
ISourceCodeHandler sourceCodeHandler)
{
if (state == null)
{
Expand All @@ -48,7 +48,7 @@ public abstract class ParseRunnerBase : IParseRunner
StateManager = parserStateManager;
_preprocessorFactory = preprocessorFactory;
_attributeParser = attributeParser;
_exporter = exporter;
_sourceCodeHandler = sourceCodeHandler;
}


Expand All @@ -67,7 +67,7 @@ private Task<ComponentParseTask.ParseCompletionArgs> FinishedParseComponentTask(
var tcs = new TaskCompletionSource<ComponentParseTask.ParseCompletionArgs>();

var preprocessor = _preprocessorFactory();
var parser = new ComponentParseTask(module, preprocessor, _attributeParser, _exporter, _state.ProjectsProvider, rewriter);
var parser = new ComponentParseTask(module, preprocessor, _attributeParser, _sourceCodeHandler, _state.ProjectsProvider, rewriter);

parser.ParseFailure += (sender, e) =>
{
Expand Down
4 changes: 2 additions & 2 deletions Rubberduck.Parsing/VBA/SynchronousParseRunner.cs
Expand Up @@ -14,12 +14,12 @@ public class SynchronousParseRunner : ParseRunnerBase
IParserStateManager parserStateManager,
Func<IVBAPreprocessor> preprocessorFactory,
IAttributeParser attributeParser,
IModuleExporter exporter)
ISourceCodeHandler sourceCodeHandler)
:base(state,
parserStateManager,
preprocessorFactory,
attributeParser,
exporter)
sourceCodeHandler)
{ }


Expand Down
@@ -1,7 +1,7 @@
using System;
using System.IO;

namespace Rubberduck.Common
namespace Rubberduck.Resources
{
public static class ApplicationConstants
{
Expand Down
1 change: 1 addition & 0 deletions Rubberduck.Resources/Rubberduck.Resources.csproj
Expand Up @@ -63,6 +63,7 @@
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="ApplicationConstants.cs" />
<Compile Include="CodeExplorer\CodeExplorerUI.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
Expand Down
12 changes: 12 additions & 0 deletions Rubberduck.VBEEditor/ISourceCodeHandler.cs
@@ -0,0 +1,12 @@
using Rubberduck.VBEditor.SafeComWrappers.Abstract;

namespace Rubberduck.VBEditor
{
public interface ISourceCodeHandler
{
string Export(IVBComponent component);
void Import(IVBComponent component, string fileName);

string Read(IVBComponent component);
}
}
1 change: 1 addition & 0 deletions Rubberduck.VBEEditor/Rubberduck.VBEditor.csproj
Expand Up @@ -66,6 +66,7 @@
<Compile Include="Factories\ISafeComWrapperProvider.cs" />
<Compile Include="Factories\VBEFactory.cs" />
<Compile Include="HashCode.cs" />
<Compile Include="ISourceCodeHandler.cs" />
<Compile Include="SafeComWrappers\Abstract\HostApplicationBase.cs" />
<Compile Include="SafeComWrappers\Abstract\ISafeComWrapper.cs" />
<Compile Include="SafeComWrappers\SafeComWrapper.cs" />
Expand Down
1 change: 1 addition & 0 deletions Rubberduck.VBEEditor/SafeComWrappers/VB/Abstract/IVBE.cs
Expand Up @@ -25,5 +25,6 @@ public interface IVBE : ISafeComWrapper, IEquatable<IVBE>

bool IsInDesignMode { get; }
int ProjectsCount { get; }
ISourceCodeHandler SourceCodeHandler { get; }
}
}
26 changes: 16 additions & 10 deletions Rubberduck.VBEEditor/SafeComWrappers/VB/Enums/VBEKind.cs
@@ -1,17 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Rubberduck.VBEditor.SafeComWrappers
namespace Rubberduck.VBEditor.SafeComWrappers
{
/// <summary>
/// Describes the kind of VB Editor.
/// </summary>
/// <remarks>
/// This is not the same as vbext_ProjectType, exposed by VBProject.Type.
/// Although the member names are similar, VBProject.Type describes the type of project (either
/// a hosted project (VBA) or a standalone project (ocx, dll, etc.), not the type of IDE.
/// </remarks>
public enum VBEKind
{
/// <summary>Embedded VB editor (Visual Basic for Applications).</summary>
Embedded,
/// <summary>
/// Hosted VB editor (Visual Basic for Applications).
/// </summary>
Hosted,

/// <summary>Standalone VB editor (Visual Basic).</summary>
/// <summary>
/// Standalone VB editor (Visual Basic).
/// </summary>
Standalone
}
}

0 comments on commit 3489486

Please sign in to comment.