Skip to content
This repository has been archived by the owner on Jan 16, 2022. It is now read-only.

Commit

Permalink
Performance optimalizations
Browse files Browse the repository at this point in the history
  • Loading branch information
cezarypiatek committed Jun 2, 2020
1 parent 5c9f37d commit 5555d24
Show file tree
Hide file tree
Showing 30 changed files with 148 additions and 135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace MappingGenerator.Test.MappingGenerator.TestCaseData

public Product ToProduct()
{
return new Product(name: Name, price: Price, category: Category, tags: Tags);
return new Product(name: this.Name, price: this.Price, category: this.Category, tags: this.Tags);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ private async Task<Document> GenerateExplicitConversion(Document document, Assig
private static async Task<(MappingEngine, SemanticModel)> CreateMappingEngine(Document document, SyntaxNode node, CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
var contextAssembly = semanticModel.FindContextAssembly(node);
var mappingEngine = await MappingEngine.Create(document, cancellationToken, contextAssembly);
var mappingEngine = await MappingEngine.Create(document, cancellationToken);
return (mappingEngine, semanticModel);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ private async Task<Document> ScaffoldInvocation(Document document, IInvocation i
{
var syntaxGenerator = SyntaxGenerator.GetGenerator(document);
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
var contextAssembly = semanticModel.FindContextAssembly(invocation.SourceNode);
var mappingSourceFinder = new ScaffoldingSourceFinder(syntaxGenerator,document, contextAssembly);
var mappingSourceFinder = new ScaffoldingSourceFinder(syntaxGenerator,document);
return await CodeFixHelper.FixInvocationWithParameters(document, invocation, namedArguments, semanticModel, mappingSourceFinder, cancellationToken);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ private async Task<Document> GenerateSplatting(Document document, IInvocation in
if (overloadParameterSets != null)
{
var syntaxGenerator = SyntaxGenerator.GetGenerator(document);
var contextAssembly = semanticModel.FindContextAssembly(invocation.SourceNode);
var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly);
var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator);
var invalidArgumentList = invocation.Arguments;
var mappingContext = new MappingContext(invocation.SourceNode, semanticModel);
var parametersMatch = FindParametersMatch(invalidArgumentList, overloadParameterSets, semanticModel, syntaxGenerator, mappingContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ public static async Task<Document> FixInvocationWithParameters(Document document
if (overloadParameterSets != null)
{
var mappingContext = new MappingContext(invocation.SourceNode, semanticModel);
var contextAssembly = semanticModel.FindContextAssembly(invocation.SourceNode);
var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly);
var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator);
var parametersMatch = MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets, mappingContext);
if (parametersMatch != null)
{
Expand Down Expand Up @@ -133,9 +132,8 @@ private static async Task<Document> CreateMappingLambda(Document document, Invoc
{
return document;
}

var contextAssembly = semanticModel.FindContextAssembly(invocation);
var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly);

var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator);
var mappingLambda = mappingEngine.CreateMappingLambda("x", sourceElementType, targetElementType, new MappingPath(), new MappingContext(invocation, semanticModel));
return await document.ReplaceNodes(invocation, invocation.WithArgumentList(SyntaxFactory.ArgumentList().AddArguments(SyntaxFactory.Argument((ExpressionSyntax)mappingLambda))), cancellationToken);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,19 @@ private static IEnumerable<IMappingSourceFinder> GetAllPossibleSourceFinders(Ini
{
var localSymbols = semanticModel.GetLocalSymbols(objectInitializer);

var queryExpression = objectInitializer.FindContainer<QueryExpressionSyntax>();
if (queryExpression != null)
{
yield return GetMappingSourceFindersForQueryExpression(semanticModel, syntaxGenerator, queryExpression, localSymbols);
yield break;
}
var container = objectInitializer.FindNearestContainer<QueryExpressionSyntax, VariableDeclaratorSyntax>();

if (objectInitializer.FindContainer<VariableDeclaratorSyntax>() is { } vds)
switch (container)
{
var leftSymbol = semanticModel.GetDeclaredSymbol(vds);
localSymbols = localSymbols.Where(ls => ls != leftSymbol).ToList();
case QueryExpressionSyntax queryExpression:
yield return GetMappingSourceFindersForQueryExpression(semanticModel, syntaxGenerator, queryExpression, localSymbols);
yield break;
case VariableDeclaratorSyntax vds:
{
var leftSymbol = semanticModel.GetDeclaredSymbol(vds);
localSymbols = localSymbols.Where(ls => ls != leftSymbol).ToList();
break;
}
}

yield return new LocalScopeMappingSourceFinder(semanticModel, localSymbols);
Expand Down Expand Up @@ -134,7 +136,7 @@ private async Task<Document> InitializeWithDefaults(Document document, Initializ
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
var syntaxGenerator = SyntaxGenerator.GetGenerator(document);
var mappingSourceFinder = new ScaffoldingSourceFinder(syntaxGenerator, document, semanticModel.FindContextAssembly(objectInitializer));
var mappingSourceFinder = new ScaffoldingSourceFinder(syntaxGenerator, document);
return await ReplaceEmptyInitializationBlock(document, objectInitializer, semanticModel, new SingleSourceMatcher(mappingSourceFinder), cancellationToken);
}

Expand All @@ -144,7 +146,7 @@ private static async Task<Document> ReplaceEmptyInitializationBlock(Document doc
{
var oldObjCreation = objectInitializer.FindContainer<ObjectCreationExpressionSyntax>();
var createdObjectType = ModelExtensions.GetTypeInfo(semanticModel, oldObjCreation).Type;
var mappingEngine = await MappingEngine.Create(document, cancellationToken, semanticModel.FindContextAssembly(objectInitializer));
var mappingEngine = await MappingEngine.Create(document, cancellationToken);

var newObjectCreation = mappingEngine.AddInitializerWithMapping(oldObjCreation, mappingMatcher, createdObjectType, new MappingContext(objectInitializer, semanticModel ));
return await document.ReplaceNodes(oldObjCreation, newObjectCreation, cancellationToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private MethodDeclarationSyntax GenerateCloneMethod(SyntaxGenerator generator)
private SyntaxNode[] CreateCloneExpression(SyntaxGenerator generator, SemanticModel semanticModel, INamedTypeSymbol type, MappingContext mappingContext)
{
//TODO: If subtypes contains clone method use it, remember about casting
var mappingEngine = new CloneMappingEngine(semanticModel, generator, type.ContainingAssembly);
var mappingEngine = new CloneMappingEngine(semanticModel, generator);
var newExpression = mappingEngine.MapExpression((ExpressionSyntax)generator.ThisExpression(), type, type, mappingContext);
return new[] { generator.ReturnStatement(newExpression).WithAdditionalAnnotations(Formatter.Annotation) };
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Threading;
using System.Threading.Tasks;
using MappingGenerator.Mappings;
using MappingGenerator.Mappings.MappingImplementors;
using MappingGenerator.Mappings.MappingMatchers;
using MappingGenerator.Mappings.SourceFinders;
using MappingGenerator.RoslynHelpers;
Expand Down Expand Up @@ -67,10 +66,9 @@ private static async Task<Document> ReplaceWithMappingBody(Document document, La
{
var methodSymbol = (IMethodSymbol)semanticModel.GetSymbolInfo(lambda).Symbol;
var createdObjectType = methodSymbol.Parameters.First().Type;
var contextAssembly = semanticModel.FindContextAssembly(lambda);
var mappingEngine = await MappingEngine.Create(document, cancellationToken, contextAssembly);
var mappingEngine = await MappingEngine.Create(document, cancellationToken);
var mappingContext = new MappingContext(lambda, semanticModel);
var propertiesToSet = MappingTargetHelper.GetFieldsThaCanBeSetPublicly(createdObjectType, contextAssembly, mappingContext);
var propertiesToSet = MappingTargetHelper.GetFieldsThaCanBeSetPublicly(createdObjectType, mappingContext);
var statements = mappingEngine.MapUsingSimpleAssignment(propertiesToSet, mappingMatcher, mappingContext, globalTargetAccessor: SyntaxFactory.IdentifierName(GetParameterIdentifier(lambda)))
.Select(x=>x.AsStatement().WithTrailingTrivia(SyntaxFactory.EndOfLine("\r\n")));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ private string GetArgumentListWithLocalVariables(Document document, IInvocation
var overloadParameterSets = invocation.GetOverloadParameterSets(semanticModel);
if (overloadParameterSets != null)
{
var contextAssembly = semanticModel.FindContextAssembly(invocation.SourceNode);
var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator, contextAssembly);
var mappingEngine = new MappingEngine(semanticModel, syntaxGenerator);
var mappingContext = new MappingContext(invocation.SourceNode, semanticModel);
var parametersMatch = MethodHelper.FindBestParametersMatch(mappingSourceFinder, overloadParameterSets, mappingContext);
if (parametersMatch != null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Linq;
using MappingGenerator.Mappings.MappingImplementors;
using MappingGenerator.RoslynHelpers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
Expand All @@ -11,8 +10,8 @@ namespace MappingGenerator.Mappings
{
public class CloneMappingEngine: MappingEngine
{
public CloneMappingEngine(SemanticModel semanticModel, SyntaxGenerator syntaxGenerator, IAssemblySymbol contextAssembly)
: base(semanticModel, syntaxGenerator, contextAssembly)
public CloneMappingEngine(SemanticModel semanticModel, SyntaxGenerator syntaxGenerator)
: base(semanticModel, syntaxGenerator)
{
}

Expand All @@ -35,7 +34,7 @@ protected override MappingElement TryToCreateMappingExpression(MappingElement so
{

var invokeClone = syntaxGenerator.InvocationExpression(syntaxGenerator.MemberAccessExpression(source.Expression, "Clone"));
var cloneMethods = targetType.GetMembers("Clone");
var cloneMethods = targetType.GetMembers("Clone").OfType<IMethodSymbol>().Where(m => mappingContext.AccessibilityHelper.IsSymbolAccessible(m, targetType)).ToList();
if (cloneMethods.Any(IsGenericCloneMethod))
{
return new MappingElement()
Expand All @@ -45,20 +44,15 @@ protected override MappingElement TryToCreateMappingExpression(MappingElement so
};
}

var objectClone = cloneMethods.FirstOrDefault(x => x is IMethodSymbol md && md.Parameters.Length == 0);
var objectClone = cloneMethods.FirstOrDefault(x => x.Parameters.Length == 0);

if (objectClone != null)
{
var objectCLoneMethod = (IMethodSymbol) objectClone;

if(CanBeAccessedInCurrentContext(objectCLoneMethod) )
return new MappingElement()
{
return new MappingElement()
{
ExpressionType = targetType,
Expression = syntaxGenerator.TryCastExpression(invokeClone, targetType) as ExpressionSyntax
};
}
ExpressionType = targetType,
Expression = syntaxGenerator.TryCastExpression(invokeClone, targetType) as ExpressionSyntax
};
}

var implicitClone = targetType.GetMembers("System.ICloneable.Clone").FirstOrDefault();
Expand All @@ -80,15 +74,8 @@ protected override MappingElement TryToCreateMappingExpression(MappingElement so
private bool IsGenericCloneMethod(ISymbol x)
{
return x is IMethodSymbol md &&
md.ReturnType.ToString().Equals("object", StringComparison.OrdinalIgnoreCase) == false &&
md.Parameters.Length == 0 &&
CanBeAccessedInCurrentContext(md);
}

private bool CanBeAccessedInCurrentContext(IMethodSymbol objectCLoneMethod)
{
return objectCLoneMethod.DeclaredAccessibility == Accessibility.Public ||
(objectCLoneMethod.DeclaredAccessibility == Accessibility.Internal && objectCLoneMethod.ContainingAssembly.IsSameAssemblyOrHasFriendAccessTo(contextAssembly));
md.ReturnType.ToString().Equals("object", StringComparison.OrdinalIgnoreCase) == false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,24 @@ public class MappingEngine
{
protected readonly SemanticModel semanticModel;
protected readonly SyntaxGenerator syntaxGenerator;
protected readonly IAssemblySymbol contextAssembly;


public MappingEngine(SemanticModel semanticModel, SyntaxGenerator syntaxGenerator, IAssemblySymbol contextAssembly)
public MappingEngine(SemanticModel semanticModel, SyntaxGenerator syntaxGenerator)
{
this.semanticModel = semanticModel;
this.syntaxGenerator = syntaxGenerator;
this.contextAssembly = contextAssembly;
}

public TypeInfo GetExpressionTypeInfo(SyntaxNode expression)
{
return semanticModel.GetTypeInfo(expression);
}

public static async Task<MappingEngine> Create(Document document, CancellationToken cancellationToken, IAssemblySymbol contextAssembly)
public static async Task<MappingEngine> Create(Document document, CancellationToken cancellationToken)
{
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
var syntaxGenerator = SyntaxGenerator.GetGenerator(document);
return new MappingEngine(semanticModel, syntaxGenerator, contextAssembly);
return new MappingEngine(semanticModel, syntaxGenerator);
}

public ExpressionSyntax MapExpression(ExpressionSyntax sourceExpression, ITypeSymbol sourceType,
Expand Down Expand Up @@ -182,7 +180,7 @@ public ObjectCreationExpressionSyntax AddInitializerWithMapping(
MappingContext mappingContext,
MappingPath mappingPath = null)
{
var propertiesToSet = MappingTargetHelper.GetFieldsThaCanBeSetPublicly(createdObjectTyp, contextAssembly, mappingContext);
var propertiesToSet = MappingTargetHelper.GetFieldsThaCanBeSetPublicly(createdObjectTyp, mappingContext);
var assignments = MapUsingSimpleAssignment(propertiesToSet, mappingMatcher, mappingContext, mappingPath).ToList();
if (assignments.Count == 0)
{
Expand All @@ -192,7 +190,7 @@ public ObjectCreationExpressionSyntax AddInitializerWithMapping(
return objectCreationExpression.WithInitializer(initializerExpressionSyntax);
}

public IEnumerable<ExpressionSyntax> MapUsingSimpleAssignment(IEnumerable<IObjectField> targets,
public IEnumerable<ExpressionSyntax> MapUsingSimpleAssignment(IReadOnlyCollection<IObjectField> targets,
IMappingMatcher mappingMatcher,
MappingContext mappingContext,
MappingPath mappingPath = null, SyntaxNode globalTargetAccessor = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ public static bool IsMappingBetweenCollections(ITypeSymbol targetClassSymbol, IT
{
return IsCollection(targetClassSymbol) && IsCollection(sourceClassSymbol);
}

public static bool IsCollection(ITypeSymbol typeSymbol)
{
return ObjectHelper.HasInterface(typeSymbol, "System.Collections.ICollection") ||
ObjectHelper.HasInterface(typeSymbol, "System.Collections.IEnumerable") ||
typeSymbol.Kind == SymbolKind.ArrayType;
return typeSymbol.Kind == SymbolKind.ArrayType || ObjectHelper.HasInterface(typeSymbol, "System.Collections.IEnumerable");
}

public static ITypeSymbol GetElementType(ITypeSymbol collectionType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ public bool CanImplement(IMethodSymbol methodSymbol)
return methodSymbol.Parameters.Length == 1 && methodSymbol.ReturnType.Equals(methodSymbol.Parameters[0].Type);
}

public IEnumerable<SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
SemanticModel semanticModel, MappingContext mappingContext)
public IEnumerable<SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator, SemanticModel semanticModel, MappingContext mappingContext)
{
var cloneMappingEngine = new CloneMappingEngine(semanticModel, generator, methodSymbol.ContainingAssembly);
var cloneMappingEngine = new CloneMappingEngine(semanticModel, generator);
var source = methodSymbol.Parameters[0];
var targetType = methodSymbol.ReturnType;
var newExpression = cloneMappingEngine.MapExpression((ExpressionSyntax)generator.IdentifierName(source.Name),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public bool CanImplement(IMethodSymbol methodSymbol)
public IEnumerable<SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
SemanticModel semanticModel, MappingContext mappingContext)
{
var mappingEngine = new MappingEngine(semanticModel, generator, methodSymbol.ContainingAssembly);
var mappingEngine = new MappingEngine(semanticModel, generator);
var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol.Parameters);
var targets = MappingTargetHelper.GetFieldsThaCanBeSetFromConstructor(methodSymbol.ContainingType, mappingContext);
return mappingEngine.MapUsingSimpleAssignment(targets, new SingleSourceMatcher(sourceFinder), mappingContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public bool CanImplement(IMethodSymbol methodSymbol)
public IEnumerable<SyntaxNode> GenerateImplementation(IMethodSymbol methodSymbol, SyntaxGenerator generator,
SemanticModel semanticModel, MappingContext mappingContext)
{
var mappingEngine = new MappingEngine(semanticModel, generator, methodSymbol.ContainingAssembly);
var mappingEngine = new MappingEngine(semanticModel, generator);
var targetType = methodSymbol.ReturnType;
var sourceFinder = new LocalScopeMappingSourceFinder(semanticModel, methodSymbol);
var objectCreationExpressionSyntax = (ObjectCreationExpressionSyntax)generator.ObjectCreationExpression(targetType);
Expand Down
Loading

0 comments on commit 5555d24

Please sign in to comment.