public void UpdateDatabase(string fileName, CXTranslationUnit TU, CancellationToken cancellationToken, bool force = false) { if (!cancellationToken.IsCancellationRequested) { if (!force) { using (var cmd = Connection.CreateCommand()) { cmd.CommandText = "SELECT LASTWRITETIME FROM TRACKING WHERE NAME=@N;"; cmd.CommandType = CommandType.Text; cmd.Parameters.AddWithValue("@N", TableName(fileName)); using (var result = cmd.ExecuteReader()) { result.Read(); string lwt = result.GetString(0); if (lwt.Equals(new FileInfo(fileName).LastWriteTime.ToString())) { return; } } } } Reset(fileName); CXCursor TUcursor = clang.getTranslationUnitCursor(TU); var parser = new TranslationUnitParser(this, fileName, cancellationToken, TUcursor); using (var tr = Connection.BeginTransaction()) { clang.visitChildren(TUcursor, parser.Visit, new CXClientData(new IntPtr(0))); tr.Commit(); } } }
private static bool TryParseTranslationUnit( string filePath, ImmutableArray <string> commandLineArgs, out CXTranslationUnit translationUnit) { // ReSharper disable BitwiseOperatorOnEnumWithoutFlags var flags = CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes | CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes | CXTranslationUnit_Flags.CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles | CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies; var index = CXIndex.Create(); var errorCode = CXTranslationUnit.TryParse( index, filePath, commandLineArgs.AsSpan(), Array.Empty <CXUnsavedFile>(), flags, out translationUnit); if (errorCode == CXErrorCode.CXError_Success) { return(translationUnit != null); } translationUnit = null !; return(false); }
public CXTranslationUnit Reparse(string name, CXUnsavedFile[] unsavedFilesArray, CancellationToken token) { lock (SyncRoot) { CXTranslationUnit TU = translationUnits [name]; if (!Loaded[name]) { if (!token.IsCancellationRequested) { clang.reparseTranslationUnit( TU, (uint)(unsavedFilesArray.Length), unsavedFilesArray, clang.defaultReparseOptions(TU) ); } } else { RemoveTranslationUnit(name); CreateTranslationUnit(name, unsavedFilesArray, true); Loaded [name] = false; TU = translationUnits [name]; } return(TU); } }
internal static extern ErrorCode clang_parseTranslationUnit2FullArgv(CXIndex index, string source_filename, [MarshalAs(UnmanagedType.LPArray)] string[] command_line_args, int num_command_line_args, [MarshalAs(UnmanagedType.LPArray)] CXUnsavedFile[] unsaved_files, uint num_unsaved_files, TranslationUnitFlags options, out CXTranslationUnit out_tu);
public void Run(string[] args, CodeBuilder result) { ParseCommandLineArgs(args, out var commandLineArgs, out var sourceContents); using (var unsavedFile = CXUnsavedFile.Create("Source", sourceContents)) using (var index = Index.Create(false, true)) { var unsavedFiles = new CXUnsavedFile[] { unsavedFile }; var handle = CXTranslationUnit.Parse( index.Handle, unsavedFile.FilenameString, commandLineArgs, unsavedFiles, CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes // Include attributed types in CXType | CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes // Implicit attributes should be visited | CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies ); var translationUnit = TranslationUnit.GetOrCreate(handle); CheckTranslationUnitErrors(translationUnit, sourceContents); VisitTranslationUnit(translationUnit); } WriteNamespace(result); }
public ClangWrapper(string filePath, CXIndex index, CXTranslationUnit translationUnit, CXCursor cursor) { FilePath = filePath; Index = index; TranslationUnit = translationUnit; Cursor = cursor; }
internal unsafe static extern CXCodeCompleteResults* clang_codeCompleteAt(CXTranslationUnit tu, string filename, uint line, uint column, CXUnsavedFile[] unsavedFiles, uint num_unsaved_files, uint options);
public bool TryParseFile(string filePath, string[] commandLineArgs, out TranslationUnit translationUnit) { // https://clang.llvm.org/doxygen/group__CINDEX__TRANSLATION__UNIT.html#ga4c8b0a3c559d14f80f78aba8c185e711 // ReSharper disable BitwiseOperatorOnEnumWithoutFlags const CXTranslationUnit_Flags flags = CXTranslationUnit_Flags.CXTranslationUnit_None | CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes | CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes; // ReSharper restore BitwiseOperatorOnEnumWithoutFlags var errorCode = CXTranslationUnit.TryParse( _index, filePath, commandLineArgs, Array.Empty <CXUnsavedFile>(), flags, out var handle); if (errorCode != CXErrorCode.CXError_Success) { translationUnit = null !; return(false); } translationUnit = TranslationUnit.GetOrCreate(handle); return(translationUnit != null); }
protected static TranslationUnit CreateTranslationUnit(string inputContents) { Assert.True(File.Exists(DefaultInputFileName)); using var unsavedFile = CXUnsavedFile.Create(DefaultInputFileName, inputContents); var unsavedFiles = new CXUnsavedFile[] { unsavedFile }; var index = CXIndex.Create(); var translationUnit = CXTranslationUnit.Parse(index, DefaultInputFileName, DefaultClangCommandLineArgs, unsavedFiles, DefaultTranslationUnitFlags); if (translationUnit.NumDiagnostics != 0) { var errorDiagnostics = new StringBuilder(); _ = errorDiagnostics.AppendLine($"The provided {nameof(CXTranslationUnit)} has the following diagnostics which prevent its use:"); var invalidTranslationUnitHandle = false; for (uint i = 0; i < translationUnit.NumDiagnostics; ++i) { using var diagnostic = translationUnit.GetDiagnostic(i); if (diagnostic.Severity is CXDiagnosticSeverity.CXDiagnostic_Error or CXDiagnosticSeverity.CXDiagnostic_Fatal) { invalidTranslationUnitHandle = true; _ = errorDiagnostics.Append(' ', 4); _ = errorDiagnostics.AppendLine(diagnostic.Format(CXDiagnosticDisplayOptions.CXDiagnostic_DisplayOption).ToString()); } } Assert.False(invalidTranslationUnitHandle, errorDiagnostics.ToString()); } return(TranslationUnit.GetOrCreate(translationUnit)); }
private async Task ValidateGeneratedBindingsAsync(string inputContents, string expectedOutputContents, PInvokeGeneratorConfigurationOptions configOptions, string[] excludedNames, IReadOnlyDictionary <string, string> remappedNames, IReadOnlyDictionary <string, IReadOnlyList <string> > withAttributes, IReadOnlyDictionary <string, string> withCallConvs, IReadOnlyDictionary <string, string> withLibraryPaths, string[] withSetLastErrors, IReadOnlyDictionary <string, string> withTypes, IReadOnlyDictionary <string, IReadOnlyList <string> > withUsings, IEnumerable <Diagnostic> expectedDiagnostics, string libraryPath) { Assert.True(File.Exists(DefaultInputFileName)); using var outputStream = new MemoryStream(); using var unsavedFile = CXUnsavedFile.Create(DefaultInputFileName, inputContents); var unsavedFiles = new CXUnsavedFile[] { unsavedFile }; var config = new PInvokeGeneratorConfiguration(libraryPath, DefaultNamespaceName, Path.GetRandomFileName(), testOutputLocation: null, configOptions, excludedNames, headerFile: null, methodClassName: null, methodPrefixToStrip: null, remappedNames, traversalNames: null, withAttributes, withCallConvs, withLibraryPaths, withSetLastErrors, withTypes, withUsings); using (var pinvokeGenerator = new PInvokeGenerator(config, (path) => outputStream)) { var handle = CXTranslationUnit.Parse(pinvokeGenerator.IndexHandle, DefaultInputFileName, DefaultClangCommandLineArgs, unsavedFiles, DefaultTranslationUnitFlags); using var translationUnit = TranslationUnit.GetOrCreate(handle); pinvokeGenerator.GenerateBindings(translationUnit); if (expectedDiagnostics is null) { Assert.Empty(pinvokeGenerator.Diagnostics); } else { Assert.Equal(expectedDiagnostics, pinvokeGenerator.Diagnostics); } } outputStream.Position = 0; var actualOutputContents = await new StreamReader(outputStream).ReadToEndAsync(); Assert.Equal(expectedOutputContents, actualOutputContents); }
internal static extern ErrorCode clang_indexTranslationUnit(CXIndexAction index_action, CXClientData client_data, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] IndexerCallbacks[] index_callbacks, uint index_callbacks_size, IndexOptionFlags index_options, CXTranslationUnit tu);
public void BasicWrapper(string name) { // Create a unique directory var dir = Path.GetRandomFileName(); _ = Directory.CreateDirectory(dir); try { // Create a file with the right name var file = new FileInfo(Path.Combine(dir, name + ".c")); File.WriteAllText(file.FullName, "int main() { return 0; }"); var index = CXIndex.Create(); var translationUnit = CXTranslationUnit.Parse(index, file.FullName, Array.Empty <string>(), Array.Empty <CXUnsavedFile>(), CXTranslationUnit_Flags.CXTranslationUnit_None); var clangFile = translationUnit.GetFile(file.FullName); var clangFileName = clangFile.Name; var clangFileNameString = clangFileName.CString; Assert.Equal(file.FullName, clangFileNameString); } finally { Directory.Delete(dir, true); } }
private static unsafe bool TryParseTranslationUnit( string filePath, ImmutableArray <string> commandLineArgs, out CXTranslationUnit translationUnit) { // ReSharper disable BitwiseOperatorOnEnumWithoutFlags const uint options = 0x00001000 | // CXTranslationUnit_IncludeAttributedTypes 0x00004000 | // CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles 0x00000040 | // CXTranslationUnit_SkipFunctionBodies 0x1 | // CXTranslationUnit_DetailedPreprocessingRecord 0x0; var index = clang_createIndex(0, 0); var cSourceFilePath = Runtime.CStrings.CString(filePath); var cCommandLineArgs = Runtime.CStrings.CStringArray(commandLineArgs.AsSpan()); CXErrorCode errorCode; fixed(CXTranslationUnit *translationUnitPointer = &translationUnit) { errorCode = clang_parseTranslationUnit2( index, cSourceFilePath, cCommandLineArgs, commandLineArgs.Length, (CXUnsavedFile *)IntPtr.Zero, 0, options, translationUnitPointer); } var result = errorCode == CXErrorCode.CXError_Success; return(result); }
public static extern CXErrorCode parseTranslationUnit2(CXIndex @CIdx, [MarshalAs(UnmanagedType.LPStr)] string @source_filename, string[] @command_line_args, int @num_command_line_args, [MarshalAs(UnmanagedType.LPArray)] CXUnsavedFile[] @unsaved_files, uint @num_unsaved_files, uint @options, out CXTranslationUnit @out_TU);
private void ParseUnit(CXTranslationUnit unit, ConcurrentDictionary <string, IClangType> parseResults) { var cursor = clang.getTranslationUnitCursor(unit); clang.visitChildren(cursor, (current, parent, p) => UnitParser(current, parseResults), default(CXClientData)); }
public Translation(CXTranslationUnit tu, File sourceFile) { this.TranslationUnit = tu; this.SourceFile = sourceFile; //clang.findReferencesInFile //clang.index_getClientEntity() //clang.getFileUniqueID //clang.getLocation(tu, ) }
private void traverse(CXTranslationUnit tu) { CXCursor root = clang.getTranslationUnitCursor(tu); CXCursorKind kind = clang.getCursorKind(root); Console.WriteLine((clang.getCursorKindSpelling(kind)).ToString()); clang.visitChildren(root, Visit, new CXClientData(new IntPtr())); }
public static Diagnostic[] CreateFrom(CXTranslationUnit tu) { var n = clang.getNumDiagnostics(tu); var diags = new Diagnostic[n]; for (int i = 0; i < diags.Length; i++) { diags[i] = new Diagnostic(clang.getDiagnostic(tu, (uint)i)); } return(diags); }
internal void ParseAndWrite() { var args = new[] { "-x", "c++", "-DWIN32", "-D_WIN32", "-DSASS2SCSS_H", // Don't include SASS2SCSS functions "-Wno-microsoft-enum-value", "-fparse-all-comments", "-fms-compatibility-version=19.00", "-I" + Path.Combine(Environment.CurrentDirectory, DefaultIncludeDir) }; var files = new List <string> { Path.Combine(Environment.CurrentDirectory, Path.Combine(DefaultIncludeDir, "sass.h")) }; // Global file _writer = _writerGlobal; WriteLine("// ----------------------------------------------------------"); WriteLine("// This file was generated automatically from sass.h headers."); WriteLine("// DO NOT EDIT THIS FILE MANUALLY"); WriteLine("// ----------------------------------------------------------"); WriteLine("using System;"); WriteLine("using System.Runtime.InteropServices;"); WriteLine("using System.Text;"); WriteLine(); WriteLine("namespace SharpScss"); WriteOpenBlock(); // Functions _writer = _writerBody; WriteLine("internal static partial class LibSass"); WriteOpenBlock(); _currentTu = Parse(files, args); clang.visitChildren(clang.getTranslationUnitCursor(_currentTu), VisitCApi, new CXClientData(IntPtr.Zero)); // Functions _writer = _writerBody; WriteCloseBlock(); // Global file _writer = _writerGlobal; _writer.Write(_writerBody); WriteCloseBlock(); }
private static ImmutableArray <CXDiagnostic> GetCompilationDiagnostics(CXTranslationUnit translationUnit) { var diagnosticsCount = (int)translationUnit.NumDiagnostics; var builder = ImmutableArray.CreateBuilder <CXDiagnostic>(diagnosticsCount); for (uint i = 0; i < diagnosticsCount; ++i) { var diagnostic = translationUnit.GetDiagnostic(i); builder.Add(diagnostic); } return(builder.ToImmutable()); }
/// <summary> /// Gets a cursor /// </summary> /// <param name="fileName"> /// A <see cref="string"/>: the filename which a Translation Unit (probably containing the cursor) is associated with. /// </param> /// <param name="location"> /// A <see cref="MonoDevelop.Ide.Editor.DocumentLocation"/>: the location in the document (named fileName) /// </param> /// <returns> /// A <see cref="CXCursor"/>: the cursor under the location /// </returns> public CXCursor GetCursor(string fileName, MonoDevelop.Ide.Editor.DocumentLocation location) { lock (SyncRoot) { CXTranslationUnit TU = translationUnits [fileName]; CXFile file = clang.getFile(TU, fileName); CXSourceLocation loc = clang.getLocation( TU, file, (uint)(location.Line), (uint)(location.Column) ); return(clang.getCursor(TU, loc)); } }
internal static extern ErrorCode clang_indexSourceFileFullArgv(CXIndexAction index_action, CXClientData client_data, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] IndexerCallbacks[] index_callbacks, uint index_callbacks_size, IndexOptionFlags index_options, string source_filename, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 7)] string[] command_line_args, int num_command_line_args, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 9)] CXUnsavedFile[] unsaved_files, uint num_unsaved_files, out CXTranslationUnit out_tu, TranslationUnitFlags tu_options);
private string GenerateCodeCSharp(CXTranslationUnit translationUnit) { Console.WriteLine("Generating C# code..."); var generator = new GeneratePlatformInvokeCodeUseCase(_state.LibraryName !); _state.Stopwatch.Restart(); var code = generator.GenerateCode(translationUnit, _state.LibraryName !); _state.Stopwatch.Stop(); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); Console.WriteLine($"Generating C# code... finished in {_state.Stopwatch.Elapsed.TotalMilliseconds} ms"); return(code); }
public AST Visit(CXTranslationUnit TU) { // set current CurrentTU = TU; // root cursor CXCursor root = clang.getTranslationUnitCursor(TU); // AST Tree AST astTree = new AST(); GCHandle astHandle = GCHandle.Alloc(astTree); // deep iterate clang.visitChildren( root, Visitor, new CXClientData((IntPtr)astHandle)); return(astTree); }
static CXToken[] Tokenize(CXTranslationUnit tu, CXSourceRange range) { IntPtr pTokens; uint numTokens; clang.tokenize(tu, range, out pTokens, out numTokens); try { var tokens = new CXToken[numTokens]; unsafe { var p = (CXToken *)pTokens.ToPointer(); for (uint i = 0; i < numTokens; i++) { tokens[i] = p[i]; } } return(tokens); } finally { clang.disposeTokens(tu, pTokens, numTokens); } }
/// <summary> /// Reparse the Translation Unit contained by this instance. /// Updates Symbol Database /// Places error markers on document /// </summary> public void ParseAndDiagnose(CancellationToken cancellationToken) { lock (Manager.SyncRoot) { var unsavedFilesArray = unsavedFiles.ToArray(); TU = Manager.Reparse(FileName, unsavedFilesArray, cancellationToken); uint numDiag = clang.getNumDiagnostics(TU); for (uint i = 0; i < numDiag; i++) { CXDiagnostic diag = clang.getDiagnostic(TU, i); string spelling = diag.ToString(); uint numRanges = clang.getDiagnosticNumRanges(diag); if (numRanges != 0) { for (uint j = 0; j < numRanges; j++) { try { SourceLocation begin = Manager.GetSourceLocation(clang.getRangeStart(clang.getDiagnosticRange(diag, j))); SourceLocation end = Manager.GetSourceLocation(clang.getRangeEnd(clang.getDiagnosticRange(diag, j))); Add(new Error(ErrorType.Error, spelling, new DocumentRegion(begin.Line, begin.Column, end.Line, end.Column))); } catch { //it seems sometimes "expression result unused" diagnostics appear multiple times //for the same problem, when there is only e.g. //an '1;' line in the code, and not every indicator has a valid filename in their location //this crashes the thread, so we ignore it } } } else { try { SourceLocation loc = Manager.GetSourceLocation(clang.getDiagnosticLocation(diag)); Add(new Error(ErrorType.Error, spelling, new DocumentRegion(loc.Line, loc.Column, loc.Line, loc.Column + 1))); } catch { //same goes here } } clang.disposeDiagnostic(diag); } Manager.UpdateDatabase(FileName, TU, cancellationToken, true); } }
/// <summary> /// Code completion wrapper to expose clang_codeCompleteAt and handle threading locks-issues. /// The caller should dispose the returned IntPtr with clang.disposeCodeCompleteResults () /// </summary> /// <param name="completionContext"> /// A <see cref="CodeCompletionContext"/> reference: the code completion context of the code completion request. /// </param> /// <param name="unsavedFiles"> /// A <see cref="CXUnsavedFile"/> array: The unsaved files in the IDE. Obligatory to have valid suggestions. /// </param> /// <param name = "fileName"></param> /// <returns>IntPtr which should be marshalled as CXCodeCompleteResults</returns> public IntPtr CodeComplete( CodeCompletionContext completionContext, CXUnsavedFile[] unsavedFiles, string fileName) { uint complete_line = (uint)(completionContext.TriggerLine); uint complete_column = (uint)(completionContext.TriggerLineOffset + 1); uint numUnsavedFiles = (uint)(unsavedFiles.Length); uint options = (uint)CXCodeComplete_Flags.IncludeCodePatterns | (uint)CXCodeComplete_Flags.IncludeCodePatterns; lock (SyncRoot) { CXTranslationUnit TU = translationUnits [fileName]; return(clang.codeCompleteAt( TU, fileName, complete_line, complete_column, unsavedFiles, numUnsavedFiles, options)); } }
public static string[] Tokenize(this CXCursor cursor, CXTranslationUnit translationUnit) { var range = clang.getCursorExtent(cursor); IntPtr nativeTokens; uint numTokens; clang.tokenize(translationUnit, range, out nativeTokens, out numTokens); var result = new List <string>(); var tokens = new CXToken[numTokens]; for (uint i = 0; i < numTokens; ++i) { tokens[i] = (CXToken)Marshal.PtrToStructure(nativeTokens, typeof(CXToken)); nativeTokens += Marshal.SizeOf(typeof(CXToken)); var name = clang.getTokenSpelling(translationUnit, tokens[i]).ToString(); result.Add(name); } return(result.ToArray()); }
internal static extern CXCursor clang_getCursor(CXTranslationUnit tu, CXSourceLocation loc);
internal static unsafe extern void clang_disposeTokens(CXTranslationUnit tu, CXToken* Tokens, uint NumTokens);
internal static extern void clang_disposeTranslationUnit(CXTranslationUnit tu);
internal static extern void clang_getInclusions(CXTranslationUnit tu, CXInclusionVisitor visitor, CXClientData clientData);
internal static extern int clang_indexTranslationUnit(CXIndexAction session, CXClientData clientData, IndexerCallbacks[] cbs, uint cbsSize, uint indexOptions, CXTranslationUnit translationUnit);
internal static extern uint clang_getNumDiagnostics(CXTranslationUnit tu);
internal static extern int clang_reparseTranslationUnit(CXTranslationUnit tu, uint numUnsavedFiles, UnsavedFile[] unsavedFiles, int options);
internal static extern CXFile clang_getFile(CXTranslationUnit tu, string filename);
internal static extern CXDiagnostic clang_getDiagnostic(CXTranslationUnit tu, uint index);
internal static extern CXSourceLocation clang_getTokenLocation(CXTranslationUnit tu, CXToken tok);
internal static unsafe extern void clang_tokenize(CXTranslationUnit tu, CXSourceRange Range, CXToken** Tokens, uint* NumTokens);
internal static extern CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu, CXFile file, uint offset);
internal static extern CXString clang_getTranslationUnitSpelling(CXTranslationUnit tu);
internal static extern CXString clang_getTokenSpelling(CXTranslationUnit tu, CXToken tok);
internal static extern CXSourceLocation clang_getLocation(CXTranslationUnit tu, CXFile file, uint line, uint column);
internal static extern CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu, CXFile fileHandle, uint offset);
internal static extern CXCursor clang_getTranslationUnitCursor(CXTranslationUnit tu);
internal static extern CXSourceRange clang_getTokenExtent(CXTranslationUnit tu, CXToken tok);
public DumpProcessor(CXTranslationUnit translationUnit) : base(translationUnit) { }
internal static extern CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit tu);