public void AllowsLongChainOfReadOnlyFields() { var source = @" class Test { private static readonly C c = new C(); public void Run() { var v = Test.c.Value.Value.Value; } } class A { public readonly int Value; } class B { public readonly A Value; } class C { public readonly B Value; }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(source); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); var code = CodeFactory.Create(method.Body, semanticModel); var expected = @" DECL v v = \literal"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code)); }
public void ProhibitsRetrievalOfArrayWithinMemberChain() { var source = @" class Test { private static readonly C c = new C(); public void Run() { var v = Test.c.Value.Value.Values; } } class A { public readonly int[] Values; } class B { public readonly A Value; } class C { public readonly B Value; }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(source); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); CodeFactory.Create(method.Body, semanticModel); }
private bool _IsSingleStepIncrement() { try { // TODO maybe change this to use symbols, but this would require more checks. var indexName = _loopIndex.Name; var incrementor = _forStatement.Incrementors.Single(); var code = CodeFactory.Create(_forStatement.Incrementors.Single(), _semanticModel); if (code.Root.Count != 1) { Debug.WriteLine($"the incrementor is not a single instruction: {incrementor}"); return(false); } var assignment = CodeFactory.Create(_forStatement.Incrementors.Single(), _semanticModel).Root.Single() as Assignment; if (assignment == null) { Debug.WriteLine($"the incrementor is not an assignment as expected"); return(false); } if (!(assignment.Left is VariableExpression assigned) || !Equals(assigned?.Name, indexName)) { Debug.WriteLine($"no incrementation of loop index"); return(false); } var equality = new ExpressionEquality(); return(equality.AreEqual(assignment.Right, new AddExpression(new VariableExpression(indexName), new IntegerExpression(1)))); } catch (UnsupportedSyntaxException e) { Debug.WriteLine($"cannot check incrementor: {e.Message}"); return(false); } }
/// <summary> /// Creates a code from the given source syntax. /// </summary> /// <returns></returns> public static Code CreateCode(string body) { var methodName = "Method"; var code = $"class Test {{ void {methodName}() {{ {body} }} }}"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(code); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); return(CodeFactory.Create(method.Body)); }
public void Create() { ICodeFactory fac = new CodeFactory(); fac.AddProvider(new GeneralCodeProvider(new GeneralCodeOptions())); var code = fac.Create(); Assert.True(code.Value.Length == 5); Assert.True(code.Validate(code.DisplayText)); }
private ISet <VariableAlias> _CollectAliases(string source) { var semanticModel = _documentFactory.CreateSemanticModel(source); var forStatement = semanticModel.SyntaxTree.GetRoot().DescendantNodes().OfType <ForStatementSyntax>().Single(); var code = CodeFactory.Create(forStatement, semanticModel); var variableAccesses = VariableAccesses.Collect(code); var cfg = ControlFlowGraphFactory.Create(code); return(ExternalArrayAliasCollector.Collect(semanticModel, forStatement, variableAccesses)); }
public void ProhibitsAccessToOutParameter() { var code = @" class Test { public void Add(out int value) { value = 5; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(code); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); CodeFactory.Create(method.Body, semanticModel); }
public void ProhibitsAccessToWritableMemberFields() { var source = @" class Test { private static int value; public void Run() { var v = Test.value; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(source); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); CodeFactory.Create(method.Body, semanticModel); }
public void ProhobitsAccessToVirtualAutoProperty() { var code = @" class Test { public virtual int Value { get; set; } public void Add(int value) { var result = Value + value; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(code); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); CodeFactory.Create(method.Body, semanticModel); }
public void ProhibitsUsageOfPropertyShadow() { var code = @" class Test { private int Value { get; set; } void Method(int Value) { var shadowed = Value; shadowed += 1 - this.Value; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(code); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); CodeFactory.Create(method.Body, semanticModel); }
public void PreventsSimultaneousUsageOfParameterShadowAndOriginalField() { var code = @" class Test { private int value; void Method(int value) { var original = this.value; var shadowed = value; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(code); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); CodeFactory.Create(method.Body, semanticModel); }
public void AllowsOriginalOnlyUsage() { var code = @" class Test { private int value; void Method(int value) { var original = this.value; original += this.value + 1; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(code); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); CodeFactory.Create(method.Body, semanticModel); }
public void Scan(TLoopStatementSyntax loopStatement, SyntaxNode body, string loopIndex, Location location) { var code = ThreeAddressCodeFactory.Create(CodeFactory.Create(body, _semanticModel)); var variableAccesses = VariableAccesses.Collect(code); if (!WriteAccessVerifier.HasNoWriteAccessToSharedVariables(variableAccesses)) { Debug.WriteLine("the loop contains write accesses to shared variables"); return; } if (_HasConflictingArrayAccesses(loopStatement, loopIndex, code, variableAccesses)) { Debug.WriteLine("the loop contains loop carried dependencies"); return; } _ReportLoopForParallelization(loopStatement, location); }
public void ProhibitsReadOnlyAccessToExpressionAutoPropertyTargettingField() { var code = @" class Test { private readonly int _value; public int Value => _value; public void Add(int value) { var result = Value + value; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(code); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); CodeFactory.Create(method.Body, semanticModel); }
public void ProhibitsAccessToPropertyWithExpressionAccessors() { var code = @" class Test { public readonly int value; public int Value { get => value; } public void Add(int value) { var result = Value + value; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(code); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); CodeFactory.Create(method.Body, semanticModel); }
public void AllowsAccessToConstMemberFieldsWithFullyQualifiedName() { var source = @" class Test { public void Run() { var pi = System.Math.PI; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(source); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); var code = CodeFactory.Create(method.Body, semanticModel); var expected = @" DECL pi pi = \literal"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code)); }
public void AllowsAccessToReadOnlyMemberFields() { var source = @" class Test { private static readonly int value; public void Run() { var v = Test.value; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(source); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Single(); var code = CodeFactory.Create(method.Body, semanticModel); var expected = @" DECL v v = \literal"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(code)); }
public void ProhibitsAccessToExpressionAutoPropertyTargettingMethod() { var code = @" class Test { public int Value => ComputeValue(); public void Add(int value) { var result = Value + value; } public int ComputeValue() { return 5; } }"; var semanticModel = DocumentFactory.Create().CreateSemanticModel(code); var method = semanticModel.SyntaxTree.GetRoot().DescendantNodes() .OfType <MethodDeclarationSyntax>() .Where(declaration => declaration.Identifier.Text.Equals("Add")) .Single(); CodeFactory.Create(method.Body, semanticModel); }