public void Main(string[] args) { var matcher = new Matcher(); matcher.AddInclude(@"**\*.cs"); matcher.AddExclude(OutputFileName); var inputFiles = new List<string>(); var latestChange = DateTime.MinValue; foreach (var f in matcher.GetResultsInFullPath(_projectDir)) { inputFiles.Add(f); var change = File.GetLastWriteTimeUtc(f); if (change > latestChange) latestChange = change; } var outputFile = Path.Combine(_projectDir, OutputFileName); if (!File.Exists(outputFile) || latestChange > File.GetLastWriteTimeUtc(outputFile)) { Console.WriteLine("Rewriting async methods in " + _projectDir); var asyncCode = new Rewriter().RewriteAndMerge(inputFiles.ToArray()); File.WriteAllText(outputFile, asyncCode); } else { Console.WriteLine("Skipping async rewriting, generated code up to date"); } }
public async Task<Document> OrganizeImportsAsync(Document document, bool placeSystemNamespaceFirst, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var rewriter = new Rewriter(placeSystemNamespaceFirst); var newRoot = rewriter.Visit(root); return document.WithSyntaxRoot(newRoot); }
public void TestConditionalAccess() { var rewriter = new Rewriter(); var root = Path.GetDirectoryName(new Uri(this.GetType().Assembly.CodeBase).LocalPath); var paths = new List<string> { "ConditionalAccess.cs" }; var result = rewriter.RewriteAndMerge(paths.Select(c => Path.Combine(root, c)).ToArray(), new[] { typeof(EnumerableExtensions).Assembly.Location }).ToArray(); Console.WriteLine(result); }
public void TestWithGenericConstraints() { var rewriter = new Rewriter(); var root = Path.GetDirectoryName(new Uri(this.GetType().Assembly.CodeBase).LocalPath); var paths = new List<string> { "IQuery.cs" }; var result = rewriter.RewriteAndMerge(paths.Select(c => Path.Combine(root, c)).ToArray()); Console.WriteLine(result); }
public void TestUsingExtensionMethods() { var rewriter = new Rewriter(); var root = Path.GetDirectoryName(new Uri(this.GetType().Assembly.CodeBase).LocalPath); var paths = new List<string> { "ExtensionMethodTests.cs", "Foo.cs" }; var result = rewriter.RewriteAndMerge(paths.Select(c => Path.Combine(root, c)).ToArray()); Console.WriteLine(result); }
public static Document Process(Document document) { var root = document.GetSyntaxRootAsync().Result; var newRoot = new Rewriter().Visit(root); if (newRoot != root) { document = document.WithSyntaxRoot(newRoot); } return document; }
public void TestTestExplicitAwaitRewrittenAsyncMethod() { var rewriter = new Rewriter(); var root = Path.GetDirectoryName(new Uri(this.GetType().Assembly.CodeBase).LocalPath); var paths = new List<string> { "TestExplicitAwaitRewrittenAsyncMethod.cs" }; var result = rewriter.RewriteAndMerge(paths.Select(c => Path.Combine(root, c)).ToArray()); Console.WriteLine(result); }
protected override async Task<Solution> ProcessAsync( Document document, SyntaxNode syntaxRoot, CancellationToken cancellationToken) { var rewriter = new Rewriter(await document.GetSemanticModelAsync(cancellationToken)); var newNode = rewriter.Visit(syntaxRoot); return document.Project.Solution.WithDocumentSyntaxRoot(document.Id, newNode); }
protected override SyntaxNode MakeSafeToAddNamespaces(SyntaxNode root, IEnumerable <INamespaceOrTypeSymbol> namespaceMembers, IEnumerable <IMethodSymbol> extensionMethods, SemanticModel model, Workspace workspace, CancellationToken cancellationToken) { var rewriter = new Rewriter(namespaceMembers, extensionMethods, model, workspace, cancellationToken); return(rewriter.Visit(root)); }
private Expression RewriteHandler(Expression body) { // // 1. Get accessors to the resulting Value and Index. // var leaveResultValue = Expression.PropertyOrField(_leaveResult, "Value"); // // 2. Compute gotos that leave the body. // var gotoScanner = new GotoScanner(_labelScanner.Labels); gotoScanner.Visit(body); // // 3. Rewrite body. // var leaveLabel = Expression.Label(typeof(LeaveHandlerData)); var rewriter = new Rewriter(leaveLabel, gotoScanner.LeaveLabels); var newBody = rewriter.Rewrite(body); // // 4. Create dispatch table. // if (gotoScanner.LeaveLabels.Count > 0) { _jumpTable.AddRange(gotoScanner.LeaveLabels.Select(kv => { var index = Expression.Constant(kv.Value); var label = kv.Key; var value = label.Type == typeof(void) ? null : Expression.Convert(leaveResultValue, label.Type); var jump = Expression.Goto(label, value); return Expression.SwitchCase(jump, index); })); } return newBody; }
/// <summary> /// Normalizes the <paramref name="methodDeclaration" />. /// </summary> protected override SyntaxNode Normalize(MethodDeclarationSyntax methodDeclaration) { var returnCount = methodDeclaration.Descendants<ReturnStatementSyntax>().Count(); // If there is no return statement within the method's body, there's nothing to do if (returnCount == 0) return methodDeclaration; // If there is only one return and it is the last method body's last statement, there's nothing to do if (returnCount == 1 && methodDeclaration.Body.Statements[methodDeclaration.Body.Statements.Count - 1] is ReturnStatementSyntax) return methodDeclaration; // Otherwise, we have to normalize the method var nameScope = methodDeclaration.GetNameScope(SemanticModel, includeLocals: true); var symbol = methodDeclaration.GetMethodSymbol(SemanticModel); _returnsValue = !symbol.ReturnsVoid; _hasReturnedVariable = SyntaxFactory.IdentifierName(nameScope.MakeUnique("hasReturned")); _returnValueVariable = _returnsValue ? SyntaxFactory.IdentifierName(nameScope.MakeUnique("returnValue")) : null; var rewriter = new Rewriter(Syntax, _hasReturnedVariable); methodDeclaration = (MethodDeclarationSyntax)rewriter.Visit(methodDeclaration); methodDeclaration = (MethodDeclarationSyntax)base.Normalize(methodDeclaration); // Generate the declarations for the local variables var hasReturnedLocal = Syntax.LocalDeclarationStatement(Syntax.TypeExpression<bool>(SemanticModel), _hasReturnedVariable.Identifier.ValueText, Syntax.FalseLiteralExpression()); var statements = methodDeclaration.Body.Statements.Insert(0, (StatementSyntax)hasReturnedLocal); if (_returnsValue) { var returnValueLocal = Syntax.LocalDeclarationStatement(symbol.ReturnType, _returnValueVariable.Identifier.ValueText); statements = statements.Insert(0, (StatementSyntax)returnValueLocal); // If the method returns a value, add the final return statement, which by now is the only one within the entire method body statements = statements.Add((StatementSyntax)Syntax.ReturnStatement(_returnValueVariable)); } return methodDeclaration.WithBody(SyntaxFactory.Block(statements)).NormalizeWhitespace(); }
public DelegateRelationshipErrorHandler(Rewriter rewriter) { _rewriter = rewriter; }
public void TestRewriteCompile(params string[] inputFiles) { var rewriter = new Rewriter(); var root = Path.Combine(Path.GetDirectoryName(new Uri(GetType().Assembly.CodeBase).LocalPath), "RewriteTests"); var files = new List <string>(inputFiles) { "RewriteAsyncAttribute.cs" }; var references = new MetadataReference[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location), MetadataReference.CreateFromFile(typeof(QueryableExtensions).Assembly.Location) }; var rewriteResult = rewriter.RewriteAndMerge(files.Select(c => Path.Combine(root, c)).ToArray(), references.Select(c => c.Display).ToArray()); Console.WriteLine(rewriteResult); var syntaxTrees = new List <SyntaxTree>(files.Select(c => CSharpSyntaxTree.ParseText(File.ReadAllText(Path.Combine(root, c)), new CSharpParseOptions(LanguageVersion.CSharp7)))) { CSharpSyntaxTree.ParseText(rewriteResult) }; var assemblyName = Path.GetRandomFileName(); var compilation = CSharpCompilation.Create( assemblyName, syntaxTrees: syntaxTrees, references: references, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); using (var ms = new MemoryStream()) { var compileResult = compilation.Emit(ms); if (!compileResult.Success) { var failures = compileResult.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error); foreach (var diagnostic in failures) { Console.Error.WriteLine(diagnostic); } Assert.Fail(); } var assembly = Assembly.Load(ms.ToArray()); var asyncMethod = assembly.DefinedTypes .SelectMany(c => c.GetMethods()) .FirstOrDefault(c => c.Name == "MainAsync" && c.IsStatic && c.GetParameters().Length == 0 && c.ReturnType.IsAssignableFromIgnoreGenericParameters(typeof(Task <>))); if (asyncMethod != null) { var task = (Task <int>)asyncMethod.Invoke(null, null); var result = task.GetAwaiter().GetResult(); if (result != 0) { Assert.Fail(); } } else { var method = assembly.DefinedTypes .SelectMany(c => c.GetMethods()) .FirstOrDefault(c => c.Name == "Main" && c.IsStatic && c.GetParameters().Length == 0); if (method != null) { if (method.ReturnType == typeof(int)) { var result = (int)method.Invoke(null, null); if (result != 0) { Assert.Fail(); } } else { method.Invoke(null, null); } } } } }
private static void MikesArchitecture(AssemblyResolver resolver, AssemblyNode assemblyNode, ContractNodes contractNodes, ContractNodes backupContracts) { #if false var originalsourceDir = Path.GetDirectoryName(assemblyNode.Location); int oldPeVerifyCode = options.verify ? PEVerify(assemblyNode.Location, originalsourceDir) : -1; #endif // Check to see if the assembly has already been rewritten if (!options.passthrough) { if (ContractNodes.IsAlreadyRewritten(assemblyNode)) { if (!options.allowRewritten) { Console.WriteLine("Assembly '" + assemblyNode.Name + "' has already been rewritten. I, your poor humble servant, cannot rewrite it. Instead I must give up without rewriting it. Help!"); } return; } } // Extract the contracts from the code (includes checking the contracts) string contractFileName = Path.GetFileNameWithoutExtension(assemblyNode.Location) + ".Contracts"; if (options.contracts == null || options.contracts.Count <= 0) contractFileName = null; if (options.contracts != null && !options.contracts.Exists(name => name.Equals(assemblyNode.Name + ".Contracts.dll", StringComparison.OrdinalIgnoreCase))) { contractFileName = null; } AssemblyNode contractAssembly = null; if (contractFileName != null) { contractAssembly = resolver.ProbeForAssembly(contractFileName, assemblyNode.Directory, resolver.DllExt); } if (!options.passthrough) { ContractNodes usedContractNodes; Extractor.ExtractContracts(assemblyNode, contractAssembly, contractNodes, backupContracts, contractNodes, out usedContractNodes, options.EmitError, false); // important to extract source before we perform any more traversals due to contract instantiation. Otherwise, // we might get copies of contracts due to instantiation that have no source text yet. // Extract the text from the sources (optional) if (usedContractNodes != null && options.extractSourceText) { GenerateDocumentationFromPDB gd = new GenerateDocumentationFromPDB(contractNodes); gd.VisitForDoc(assemblyNode); } // After all contracts have been extracted in assembly, do some post-extractor checks // we run these even if no contracts were extracted due to checks having to do with overrides var contractNodesForChecks = usedContractNodes != null ? usedContractNodes : contractNodes; if (contractNodesForChecks != null) { PostExtractorChecker pec = new PostExtractorChecker(contractNodesForChecks, options.EmitError, false, options.fSharp, options.IsLegacyModeAssembly, options.addInterfaceWrappersWhenNeeded, options.level); if (contractAssembly != null) { pec.VisitForPostCheck(contractAssembly); } else { pec.VisitForPostCheck(assemblyNode); } } // don't really need to test, since if they are the same, the assignment doesn't change that // but this is to emphasize that the nodes used in the AST by the extractor are different // than what we thought we were using. if (options.GetErrorCount() > 0) { // we are done. // But first, report any metadata errors so they are not masked by the errors CheckForMetaDataErrors(assemblyNode); return; } } // If we have metadata errors, cop out { #if false for (int i = 0; i < assemblyNode.ModuleReferences.Count; i++) { Module m = assemblyNode.ModuleReferences[i].Module; Console.WriteLine("Location for referenced module '{0}' is '{1}'", m.Name, m.Location); } #endif if (CheckForMetaDataErrors(assemblyNode)) { throw new Exception("Rewrite aborted due to metadata errors. Check output window"); } for (int i = 0; i < assemblyNode.AssemblyReferences.Count; i++) { AssemblyNode aref = assemblyNode.AssemblyReferences[i].Assembly; if (CheckForMetaDataErrors(aref)) { throw new Exception("Rewrite aborted due to metadata errors. Check output window"); } } } // Inject the contracts into the code (optional) if (options.rewrite && !options.passthrough) { // Rewrite the assembly in memory. ContractNodes cnForRuntime = null; // make sure to use the correct contract nodes for runtime code generation. We may have Contractnodes pointing to microsoft.Contracts even though // the code relies on mscorlib to provide the contracts. So make sure the code references the contract nodes first. if (contractNodes != null && contractNodes.ContractClass != null && contractNodes.ContractClass.DeclaringModule != SystemTypes.SystemAssembly) { string assemblyNameContainingContracts = contractNodes.ContractClass.DeclaringModule.Name; for (int i = 0; i < assemblyNode.AssemblyReferences.Count; i++) { if (assemblyNode.AssemblyReferences[i].Name == assemblyNameContainingContracts) { cnForRuntime = contractNodes; break; // runtime actually references the contract library } } } if (cnForRuntime == null) { // try to grab the system assembly contracts cnForRuntime = ContractNodes.GetContractNodes(SystemTypes.SystemAssembly, null); } if (cnForRuntime == null) { // Can happen if the assembly does not use contracts directly, but inherits them from some other place // Use the normal contractNodes in this case (actually we should generate whatever we grab from ContractNodes) cnForRuntime = contractNodes; } RuntimeContractMethods runtimeContracts = new RuntimeContractMethods(userSpecifiedContractType, cnForRuntime, assemblyNode, options.throwOnFailure, options.level, options.publicSurfaceOnly, options.callSiteRequires, options.recursionGuard, options.hideFromDebugger, options.IsLegacyModeAssembly); Rewriter rewriter = new Rewriter(assemblyNode, runtimeContracts, options.EmitError, options.inheritInvariants, options.skipQuantifiers); rewriter.Verbose = 0 < options.verbose; rewriter.Visit(assemblyNode); // Perform this check only when there are no out-of-band contracts in use due to rewriter bug #336 if (contractAssembly == null) { PostRewriteChecker checker = new PostRewriteChecker(options.EmitError); checker.Visit(assemblyNode); } } //Console.WriteLine(">>>Finished Rewriting<<<"); // Set metadata version for target the same as for the source TargetPlatform.TargetRuntimeVersion = assemblyNode.TargetRuntimeVersion; // Write out the assembly (optional) if (options.rewrite || options.passthrough) { bool updateInPlace = options.output == "same"; string pdbFile = Path.ChangeExtension(options.assembly, ".pdb"); bool pdbExists = File.Exists(pdbFile); string backupAssembly = options.assembly + ".original"; string backupPDB = pdbFile + ".original"; if (updateInPlace) { // Write the rewritten assembly in a temporary location. options.output = options.assembly; MoveAssemblyFileAndPDB(options.output, pdbFile, pdbExists, backupAssembly, backupPDB); } // Write the assembly. // Don't pass the debugInfo flag to WriteModule unless the PDB file exists. assemblyNode.WriteModule(options.output, options.debug && pdbExists && options.writePDBFile); string outputDir = updateInPlace ? Path.GetDirectoryName(options.assembly) : Path.GetDirectoryName(options.output); // Re-attach external file resources to the new output assembly. MoveModuleResources(assemblyNode, outputDir); #if false if (oldPeVerifyCode == 0) { var newPeVerifyCode = PEVerify(assemblyNode.Location, originalsourceDir); if (newPeVerifyCode > 0) { if (updateInPlace) { // move original back in place MoveAssemblyFileAndPDB(backupAssembly, backupPDB, pdbExists, options.output, pdbFile); } throw new Exception("Rewrite failed to produce verifiable assembly"); } else if (newPeVerifyCode == 0) { Console.WriteLine("rewriter output verified"); } } #endif if (updateInPlace) { if (!options.keepOriginalFiles) { try { File.Delete(backupAssembly); } catch { // there are situations where the exe is still in use } if (options.debug && pdbExists && options.writePDBFile) { try { File.Delete(backupPDB); } catch { // I know this is stupid, but somehow on some machines we get an AccessError trying to delete the pdb. // so we leave it in place. } } } } } }
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken) { var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var curlyBracketToken = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start); var curlyBracketLine = curlyBracketToken.GetLineSpan().StartLinePosition.Line; var curlyBracketReplacementToken = curlyBracketToken; var indentationOptions = IndentationOptions.FromDocument(document); var indentationSteps = DetermineIndentationSteps(indentationOptions, curlyBracketToken); var previousToken = curlyBracketToken.GetPreviousToken(); var nextToken = curlyBracketToken.GetNextToken(); var rewriter = new Rewriter(); if (IsAccessorWithSingleLineBlock(previousToken, curlyBracketToken)) { var newTrailingTrivia = previousToken.TrailingTrivia .WithoutTrailingWhitespace() .Add(SyntaxFactory.Space); rewriter.AddReplacement(previousToken, previousToken.WithTrailingTrivia(newTrailingTrivia)); curlyBracketReplacementToken = curlyBracketReplacementToken.WithLeadingTrivia(curlyBracketToken.LeadingTrivia.WithoutLeadingWhitespace()); } else { // Check if we need to apply a fix before the curly bracket if (previousToken.GetLineSpan().StartLinePosition.Line == curlyBracketLine) { var sharedTrivia = curlyBracketReplacementToken.LeadingTrivia.WithoutTrailingWhitespace(); var previousTokenNewTrailingTrivia = previousToken.TrailingTrivia .WithoutTrailingWhitespace() .AddRange(sharedTrivia) .Add(SyntaxFactory.CarriageReturnLineFeed); rewriter.AddReplacement(previousToken, previousToken.WithTrailingTrivia(previousTokenNewTrailingTrivia)); curlyBracketReplacementToken = curlyBracketReplacementToken.WithLeadingTrivia(IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, indentationSteps)); } // Check if we need to apply a fix after the curly bracket // if a closing curly bracket is followed by a semi-colon or closing paren, no fix is needed. if ((nextToken.GetLineSpan().StartLinePosition.Line == curlyBracketLine) && (!curlyBracketToken.IsKind(SyntaxKind.CloseBraceToken) || !IsValidFollowingToken(nextToken))) { var sharedTrivia = nextToken.LeadingTrivia.WithoutTrailingWhitespace(); var newTrailingTrivia = curlyBracketReplacementToken.TrailingTrivia .WithoutTrailingWhitespace() .AddRange(sharedTrivia) .Add(SyntaxFactory.CarriageReturnLineFeed); int newIndentationSteps; if (curlyBracketToken.IsKind(SyntaxKind.OpenBraceToken)) { newIndentationSteps = indentationSteps + 1; } else if (nextToken.IsKind(SyntaxKind.CloseBraceToken)) { newIndentationSteps = Math.Max(0, indentationSteps - 1); } else { newIndentationSteps = indentationSteps; } rewriter.AddReplacement(nextToken, nextToken.WithLeadingTrivia(IndentationHelper.GenerateWhitespaceTrivia(indentationOptions, newIndentationSteps))); curlyBracketReplacementToken = curlyBracketReplacementToken.WithTrailingTrivia(newTrailingTrivia); } } rewriter.AddReplacement(curlyBracketToken, curlyBracketReplacementToken); var newSyntaxRoot = rewriter.Visit(syntaxRoot).WithoutFormatting(); return document.WithSyntaxRoot(newSyntaxRoot); }
protected override async Task<Document> ProcessAsync(Document document, IEnumerable<ISyntaxOrganizer> organizers, CancellationToken cancellationToken) { var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var rewriter = new Rewriter(this, organizers, await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false), cancellationToken); return document.WithSyntaxRoot(rewriter.Visit(root)); }
public void TestTestGenericSpecialisedImplementation() { var rewriter = new Rewriter(); var root = Path.GetDirectoryName(new Uri(this.GetType().Assembly.CodeBase).LocalPath); var paths = new List<string> { "TestGenericSpecialisedImplementation.cs" }; var result = rewriter.RewriteAndMerge(paths.Select(c => Path.Combine(root, c)).ToArray()); Console.WriteLine(result); }
/// <summary> /// Create a <see cref="RelationshipErrorHandler"/> that simply rewrites the invalid target Uri. /// </summary> /// <param name="rewriter">The delegate used to rewrite the Uri.</param> /// <returns>A factory function for use in <see cref="OpenSettings.RelationshipErrorHandlerFactory"/>.</returns> public static Func <OpenXmlPackage, RelationshipErrorHandler> CreateRewriterFactory(Rewriter rewriter) { var handler = new DelegateRelationshipErrorHandler(rewriter); return(_ => handler); }
public SyntaxNode Compile(SyntaxNode node) { Debug.Assert(Rewriter != null); return(Rewriter.Visit(node)); }
public static SyntaxNode RemoveAttributeKeyworkHelper(SyntaxNode initialSourceNode) { initialSourceNode = new Rewriter().Visit(initialSourceNode); return(initialSourceNode); }
private static void KaelsArchitecture(AssemblyNode assemblyNode) { // Finish decompiling expressions where CCI left off. new Abnormalizer().Visit(assemblyNode); // Check and extract all inline foxtrot contracts and place them in the object model. Checker checker = new Checker(new ContractNodes(assemblyNode)); bool errorFound = false; checker.ErrorFound += delegate(System.CodeDom.Compiler.CompilerError error) { if (!error.IsWarning || warningLevel > 0) { Console.WriteLine(error.ToString()); } errorFound |= !error.IsWarning; }; checker.Visit(assemblyNode); if (errorFound) return; if (verify) { throw new NotImplementedException("Static verification is not yet implemented."); } // Write out the assembly, possibly injecting the runtime checks if (rewrite || passthrough) { // Reload the assembly to flush out the abnormalized contracts since the rewriter can't handle them yet. assemblyNode = LoadAssembly(); if (!passthrough) { // Rewrite the assembly in memory. Rewriter rewriter = new Rewriter(new ContractNodes(assemblyNode)); rewriter.InlinePreconditions = false; rewriter.InlinePostconditions = false; rewriter.InlineInvariant = false; rewriter.Verbose = verbose; rewriter.Decompile = decompile; rewriter.Visit(assemblyNode); } if (output == "same") { // Save the rewritten assembly to a temporary location. output = Path.Combine(Path.GetTempPath(), Path.GetFileName(assembly)); // Re-attach external file resources to the new output assembly. MoveModuleResources(assemblyNode, output); // Save the rewritten assembly. assemblyNode.WriteModule(output, debug); // Make a copy of the original assembly and PDB. File.Delete(assembly + ".original"); File.Delete(Path.ChangeExtension(assembly, ".pdb") + ".original"); File.Move(assembly, assembly + ".original"); File.Move(Path.ChangeExtension(assembly, ".pdb"), Path.ChangeExtension(assembly, ".pdb") + ".original"); // Move the rewritten assembly and PDB to the original location. File.Move(output, assembly); File.Move(Path.ChangeExtension(output, ".pdb"), Path.ChangeExtension(assembly, ".pdb")); } else { // Re-attach external file resources to the new output assembly. MoveModuleResources(assemblyNode, output); // Save the rewritten assembly. assemblyNode.WriteModule(output, debug); } } }
public override object VisitClass_declaration([NotNull] CSharpParser.Class_declarationContext context) { _currentClass.Push(context.identifier().GetText()); var typeParameters = _serviceFile.ServiceDeclaration.TypeParameters; var currentNamespace = GetCurrentNamespace(); bool isTypeParamsMatch = true; var typeParams = context?.type_parameter_list()?.type_parameter(); if (!(typeParams is null && (typeParameters is null || typeParameters.Count == 0))) { if ((typeParams?.Length ?? 0) != (typeParameters?.Count ?? 0)) { isTypeParamsMatch = false; } else { for (int i = 0; i < typeParams.Length; ++i) { if (typeParams[i].identifier().GetText() != typeParameters[i].TypeParam) { isTypeParamsMatch = false; break; } } } } if (GetCurrentClass() == _serviceClassInterfaceName && currentNamespace == _serviceFile.ServiceNamespace && isTypeParamsMatch) { _isCorrectClass.Push(true); _hasServiceClass = true; } else { _isCorrectClass.Push(false); } VisitChildren(context); if (_isCorrectClass.Peek()) { _hasServiceClass = true; var preclassWhitespace = Tokens.GetHiddenTokensToLeft(context.Start.TokenIndex, Lexer.Hidden); int tabLevels = 1 + ((preclassWhitespace?.Count ?? 0) > 0 ? _stringUtilService.CalculateTabLevels(preclassWhitespace[0]?.Text ?? string.Empty, _tabString) : 0); int?finalProperty = null; int?finalMethod = null; int?finalField = null; int?finalConstantOrField = null; int?finalConstructorOrDestructor = null; var members = context?.class_body()?.class_member_declarations()?.class_member_declaration(); if (members != null) { foreach (var member in members) { if (member.method_declaration() != null) { finalMethod = member.method_declaration().Stop.TokenIndex; } else if (member.property_declaration() != null) { finalProperty = member.property_declaration().Stop.TokenIndex; } else if (member.constant_declaration() != null) { finalConstantOrField = member.constant_declaration().Stop.TokenIndex; } else if (member.field_declaration() != null) { finalConstantOrField = member.field_declaration().Stop.TokenIndex; finalField = member.field_declaration().Stop.TokenIndex; } else if (member.constructor_declaration() != null) { finalConstructorOrDestructor = member.constructor_declaration().Stop.TokenIndex; } else if (member.static_constructor_declaration() != null) { finalConstructorOrDestructor = member.static_constructor_declaration().Stop.TokenIndex; } else if (member.destructor_declaration() != null) { finalConstructorOrDestructor = member.destructor_declaration().Stop.TokenIndex; } } } int fieldStopIndex = finalField ?? finalConstantOrField ?? context.class_body().OPEN_BRACE().Symbol.TokenIndex; int?constructorStopIndex = null; int?propertyStopIndex = null; int?methodStopIndex = null; var fieldStringBuilder = new StringBuilder(); StringBuilder constructorStringBuilder = null; StringBuilder propertyStringBuilder = null; StringBuilder methodStringBuilder = null; if (_fieldDict.Keys.Count > 0) { // add fields foreach (var field in _fieldDict.Values) { fieldStringBuilder.Append(_cSharpParserService.GenerateFieldDeclaration( field, tabLevels, _tabString)); } } if (!_hasServiceConstructor) { // add ctor constructorStopIndex = finalProperty ?? finalConstantOrField ?? fieldStopIndex; constructorStringBuilder = constructorStopIndex == fieldStopIndex ? fieldStringBuilder : new StringBuilder(); constructorStringBuilder.Append(_cSharpParserService.GenerateConstructorDeclaration( _serviceFile.ServiceDeclaration.Body.ConstructorDeclaration, tabLevels, _tabString)); } if (_serviceFile.ServiceDeclaration.Body?.PropertyDeclarations != null && _serviceFile.ServiceDeclaration.Body.PropertyDeclarations.Count > 0) { // add properties propertyStopIndex = finalProperty ?? finalConstructorOrDestructor ?? constructorStopIndex ?? fieldStopIndex; propertyStringBuilder = propertyStopIndex == fieldStopIndex ? fieldStringBuilder : (propertyStopIndex == constructorStopIndex ? constructorStringBuilder : new StringBuilder()); propertyStringBuilder.Append( _cSharpParserService.GeneratePropertyDeclarations( _serviceFile.ServiceDeclaration.Body.PropertyDeclarations, tabLevels, _tabString)); } if (_serviceFile.ServiceDeclaration.Body?.MethodDeclarations != null && _serviceFile.ServiceDeclaration.Body.MethodDeclarations.Count > 0) { // add methods methodStopIndex = finalMethod ?? finalProperty ?? finalConstructorOrDestructor ?? constructorStopIndex ?? fieldStopIndex; methodStringBuilder = methodStopIndex == fieldStopIndex ? fieldStringBuilder : (methodStopIndex == constructorStopIndex ? constructorStringBuilder : (methodStopIndex == propertyStopIndex ? propertyStringBuilder : new StringBuilder())); methodStringBuilder.Append( _cSharpParserService.GenerateMethodDeclarations( _serviceFile.ServiceDeclaration.Body.MethodDeclarations, tabLevels, _tabString)); } var fieldString = fieldStringBuilder.ToString(); if (fieldString.Length > 0) { IsModified = true; Rewriter.InsertAfter(fieldStopIndex, fieldString); } if (constructorStringBuilder != null && constructorStopIndex != fieldStopIndex) { var constructorString = constructorStringBuilder.ToString(); if (constructorString.Length > 0) { IsModified = true; Rewriter.InsertAfter(constructorStopIndex ?? -1, constructorString); } } if (propertyStringBuilder != null && propertyStopIndex != constructorStopIndex && propertyStopIndex != fieldStopIndex) { var propertyString = propertyStringBuilder.ToString(); if (propertyString.Length > 0) { IsModified = true; Rewriter.InsertAfter(propertyStopIndex ?? -1, propertyString); } } if (methodStringBuilder != null && methodStopIndex != constructorStopIndex && methodStopIndex != fieldStopIndex && methodStopIndex != propertyStopIndex) { var methodString = methodStringBuilder.ToString(); if (methodString.Length > 0) { IsModified = true; Rewriter.InsertAfter(methodStopIndex ?? -1, methodString); } } } _ = _isCorrectClass.Pop(); _ = _currentClass.Pop(); return(null); }
public override object VisitConstructor_declaration( [NotNull] CSharpParser.Constructor_declarationContext context) { if (_isCorrectClass.Peek()) { _hasServiceConstructor = true; var preCtorWhitespace = Tokens.GetHiddenTokensToLeft(context.Start.TokenIndex, Lexer.Hidden); int tabLevels = 1 + ((preCtorWhitespace?.Count ?? 0) > 0 ? _stringUtilService.CalculateTabLevels(preCtorWhitespace[0]?.Text ?? string.Empty, _tabString) : 0); var fixedParams = context?.constructor_declarator()?.formal_parameter_list()?.fixed_parameters() ?.fixed_parameter(); if (fixedParams != null) { foreach (var fixedParam in fixedParams) { var paramName = $"{fixedParam.type_().GetText()} {fixedParam.identifier().GetText()}"; if (_ctorParamDict.ContainsKey(paramName)) { _ctorParamDict.Remove(paramName); } } } var ctorStatements = context?.constructor_body()?.block()?.statement_list(); if (ctorStatements != null) { foreach (var statement in ctorStatements.statement()) { var minStatement = _cSharpParserService.GetTextWithWhitespaceMinified(Tokens, statement); if (_ctorAssignmentDict.ContainsKey(minStatement)) { _ctorAssignmentDict.Remove(minStatement); } } } if (_ctorParamDict.Keys.Count > 0) { // add params var ctorParams = _ctorParamDict.Values.ToList(); var formalParamList = context?.constructor_declarator()?.formal_parameter_list(); var finalFixedParam = context?.constructor_declarator() ?.formal_parameter_list() ?.fixed_parameters() ?.fixed_parameter() ?.Last(); int fixedParamStopIndex = finalFixedParam?.Stop?.TokenIndex ?? context.constructor_declarator().OPEN_PARENS().Symbol.TokenIndex; var paramStringBuilder = new StringBuilder(); if (finalFixedParam != null) { var preFinalParamWhitespace = Tokens.GetHiddenTokensToLeft( finalFixedParam?.Start?.TokenIndex ?? -1, Lexer.Hidden); int finalParamtabs = (preFinalParamWhitespace?.Count ?? 0) > 0 ? _stringUtilService.CalculateTabLevels(preFinalParamWhitespace[0]?.Text ?? string.Empty, _tabString) : 0; if (finalParamtabs > 0) { paramStringBuilder.Append(_cSharpParserService.GenerateFixedParameters( ctorParams, tabLevels, _tabString)); if (formalParamList?.parameter_array() != null) { var preParamArrayWhitespaceArray = Tokens.GetHiddenTokensToLeft( formalParamList.parameter_array().Start.TokenIndex, Lexer.Hidden); string preParamArrayWhitespace = preParamArrayWhitespaceArray.Count > 0 ? preParamArrayWhitespaceArray[0].Text : string.Empty; if (!Regex.IsMatch(preParamArrayWhitespace, @"\r?\n")) { IsModified = true; Rewriter.InsertBefore( formalParamList.parameter_array().Start.TokenIndex, "\r\n" + _stringUtilService.TabString(string.Empty, finalParamtabs, _tabString)); } } } else { paramStringBuilder.Append(_cSharpParserService.GenerateFixedParameters( ctorParams, tabLevels, _tabString, false, true)); } } else { paramStringBuilder.Append(_cSharpParserService.GenerateFixedParameters( ctorParams, tabLevels, _tabString, true)); if (formalParamList?.parameter_array() != null) { var preParamArrayWhitespaceArray = Tokens.GetHiddenTokensToLeft( formalParamList.parameter_array().Start.TokenIndex, Lexer.Hidden); string preParamArrayWhitespace = preParamArrayWhitespaceArray.Count > 0 ? preParamArrayWhitespaceArray[0].Text : string.Empty; if (!Regex.IsMatch(preParamArrayWhitespace, $"\r?\n")) { IsModified = true; Rewriter.InsertBefore( formalParamList.parameter_array().Start.TokenIndex, "\r\n" + _stringUtilService.TabString(string.Empty, tabLevels, _tabString)); } } } var paramString = paramStringBuilder.ToString(); if (paramString.Length > 0) { IsModified = true; Rewriter.InsertAfter(fixedParamStopIndex, paramString); } } if (_ctorAssignmentDict.Keys.Count > 0) { var ctorAssignments = _ctorAssignmentDict.Values.ToList(); var assignmentsString = _cSharpParserService.GenerateSimpleAssignments( ctorAssignments, tabLevels, _tabString); var constructorBody = context?.constructor_body(); if (constructorBody.SEMICOLON() != null) { var conBodyBuilder = new StringBuilder(); conBodyBuilder.Append("\r\n"); conBodyBuilder.Append(_stringUtilService.TabString("{", tabLevels - 1, _tabString)); conBodyBuilder.Append(assignmentsString); conBodyBuilder.Append("\r\n"); conBodyBuilder.Append(_stringUtilService.TabString("}", tabLevels - 1, _tabString)); IsModified = true; Rewriter.Replace(constructorBody.SEMICOLON().Symbol.TokenIndex, conBodyBuilder.ToString()); } else { var block = constructorBody.block(); int?finalAssignment = block.statement_list()?.statement()?.Last()?.Stop?.TokenIndex; int assignmentStopIndex = finalAssignment ?? block.OPEN_BRACE().Symbol.TokenIndex; var assignmentStringBuilder = new StringBuilder(); assignmentStringBuilder.Append(assignmentsString); var postAssignmentStopWhitespaceArray = Tokens.GetHiddenTokensToRight( assignmentStopIndex, Lexer.Hidden); string postAssignmentStopWhitespace = postAssignmentStopWhitespaceArray.Count > 0 ? postAssignmentStopWhitespaceArray[0].Text : string.Empty; if (!Regex.IsMatch(postAssignmentStopWhitespace, @"\r?\n")) { assignmentStringBuilder.Append("\r\n"); } var assignmentString = assignmentStringBuilder.ToString(); if (assignmentString.Length > 0) { IsModified = true; Rewriter.InsertAfter(assignmentStopIndex, assignmentString); } } } } VisitChildren(context); return(null); }
public void Setup() { this.arch = new M68kArchitecture("m68k"); this.addrInstr = Address.Ptr32(0x0012340C); this.rw = new Rewriter(this.arch, null, new M68kState(arch), new Frame(arch.FramePointerType), null); }
private async Task<Document> MoveDeclarationNearReferenceAsync(Document document, State state, CancellationToken cancellationToken) { var innermostStatements = state.InnermostBlock.Statements.Where(s => s != state.DeclarationStatement).ToList(); var innermostAffectedIndex = innermostStatements.IndexOf(state.FirstStatementAffectedInInnermostBlock); var crossesMeaningfulBlock = CrossesMeaningfulBlock(state); var warningAnnotation = crossesMeaningfulBlock ? WarningAnnotation.Create(CSharpFeaturesResources.Warning_colon_Declaration_changes_scope_and_may_change_meaning) : null; var canMergeDeclarationAndAssignment = await CanMergeDeclarationAndAssignmentAsync(document, state, cancellationToken).ConfigureAwait(false); if (canMergeDeclarationAndAssignment) { // Replace the first reference with a new declaration. var declarationStatement = CreateMergedDeclarationStatement(state, state.FirstStatementAffectedInInnermostBlock); declarationStatement = warningAnnotation == null ? declarationStatement : declarationStatement.WithAdditionalAnnotations(warningAnnotation); innermostStatements[innermostAffectedIndex] = declarationStatement.WithAdditionalAnnotations(Formatter.Annotation); } else { // If we're not merging with an existing declaration, make the declaration semantically // explicit to improve the chances that it won't break code. var explicitDeclarationStatement = await Simplifier.ExpandAsync(state.DeclarationStatement, document, cancellationToken: cancellationToken).ConfigureAwait(false); // place the declaration above the first statement that references it. var declarationStatement = warningAnnotation == null ? explicitDeclarationStatement : explicitDeclarationStatement.WithAdditionalAnnotations(warningAnnotation); innermostStatements.Insert(innermostAffectedIndex, declarationStatement.WithAdditionalAnnotations(Formatter.Annotation)); } var newInnermostBlock = state.InnermostBlock.WithStatements( SyntaxFactory.List<StatementSyntax>(innermostStatements)).WithAdditionalAnnotations(Formatter.Annotation); var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); var rewriter = new Rewriter(state.InnermostBlock, newInnermostBlock, state.OutermostBlock, state.DeclarationStatement); var newRoot = rewriter.Visit(tree.GetRoot(cancellationToken)); return document.WithSyntaxRoot(newRoot); }
protected override async Task FixAllAsync( Document document, ImmutableArray <Diagnostic> diagnostics, SyntaxEditor editor, CancellationToken cancellationToken ) { using var spansDisposer = ArrayBuilder <TextSpan> .GetInstance( diagnostics.Length, out var spans ); foreach (var diagnostic in diagnostics) { cancellationToken.ThrowIfCancellationRequested(); var switchLocation = diagnostic.AdditionalLocations[0]; if (spans.Any((s, nodeSpan) => s.Contains(nodeSpan), switchLocation.SourceSpan)) { // Skip nested switch expressions in case of a fix-all operation. continue; } spans.Add(switchLocation.SourceSpan); var properties = diagnostic.Properties; var nodeToGenerate = (SyntaxKind)int.Parse(properties[Constants.NodeToGenerateKey]); var shouldRemoveNextStatement = bool.Parse( properties[Constants.ShouldRemoveNextStatementKey] ); var declaratorToRemoveLocationOpt = diagnostic.AdditionalLocations.ElementAtOrDefault(1); var semanticModel = await document .GetSemanticModelAsync(cancellationToken) .ConfigureAwait(false); SyntaxNode declaratorToRemoveNodeOpt = null; ITypeSymbol declaratorToRemoveTypeOpt = null; if (declaratorToRemoveLocationOpt != null) { declaratorToRemoveNodeOpt = declaratorToRemoveLocationOpt.FindNode( cancellationToken ); declaratorToRemoveTypeOpt = semanticModel .GetDeclaredSymbol(declaratorToRemoveNodeOpt, cancellationToken) .GetSymbolType(); } var switchStatement = (SwitchStatementSyntax)switchLocation.FindNode( getInnermostNodeForTie: true, cancellationToken ); var switchExpression = Rewriter.Rewrite( switchStatement, semanticModel, declaratorToRemoveTypeOpt, nodeToGenerate, shouldMoveNextStatementToSwitchExpression: shouldRemoveNextStatement, generateDeclaration: declaratorToRemoveLocationOpt is object ); editor.ReplaceNode( switchStatement, switchExpression.WithAdditionalAnnotations(Formatter.Annotation) ); if (declaratorToRemoveLocationOpt is object) { editor.RemoveNode(declaratorToRemoveLocationOpt.FindNode(cancellationToken)); } if (shouldRemoveNextStatement) { // Already morphed into the top-level switch expression. SyntaxNode nextStatement = switchStatement.GetNextStatement(); Debug.Assert( nextStatement.IsKind(SyntaxKind.ThrowStatement, SyntaxKind.ReturnStatement) ); editor.RemoveNode( nextStatement.IsParentKind(SyntaxKind.GlobalStatement) ? nextStatement.Parent : nextStatement ); } } }
public override async Task<Document> AddAsync( IEnumerable<ISymbol> members, bool placeSystemNamespaceFirst, CodeGenerationOptions options, CancellationToken cancellationToken) { var importsContainerToMissingNamespaces = await DetermineNamespaceToImportAsync(members, options, cancellationToken).ConfigureAwait(false); if (importsContainerToMissingNamespaces.Count == 0) { return this.Document; } var root = await this.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var rewriter = new Rewriter(this.Document, importsContainerToMissingNamespaces, options.PlaceSystemNamespaceFirst, cancellationToken); var newRoot = rewriter.Visit(root); return this.Document.WithSyntaxRoot(newRoot); }
public AsyncRewriterTask() { this.rewriter = new Rewriter(); }