public DocumentSnapshot( string path, long textVersion, Microsoft.CodeAnalysis.VersionStamp stamp, SourceText text) { Path = path; TextVersion = textVersion; _text = text; DocumentVersion = stamp; }
public DocumentSnapshot( string path, long textVersion, Microsoft.CodeAnalysis.VersionStamp stamp, TextLoader loader) { Path = path; TextVersion = textVersion; DocumentVersion = stamp; _loader = loader; }
/// <summary> /// Gets the version of the document's top level signature if it is already loaded and available. /// </summary> internal bool TryGetTopLevelChangeTextVersion(out VersionStamp version) => DocumentState.TryGetTopLevelChangeTextVersion(out version);
public ProjectInfo WithVersion(VersionStamp version) { return(With(attributes: Attributes.With(version: version))); }
/// <summary> /// Create a new empty solution instance associated with this workspace. /// </summary> protected internal Solution CreateSolution(SolutionId id) { return(CreateSolution(SolutionInfo.Create(id, VersionStamp.Create()))); }
/// <summary> /// Gets the version of the document's top level signature if it is already loaded and available. /// </summary> internal bool TryGetTopLevelChangeTextVersion(out VersionStamp version) { return(_state.TryGetTopLevelChangeTextVersion(out version)); }
internal static bool TryGetReference( SolutionState solution, ProjectReference projectReference, Compilation finalOrDeclarationCompilation, VersionStamp version, out MetadataReference reference) { // if we have one from snapshot cache, use it. it will make sure same compilation will get same metadata reference always. MetadataOnlyReferenceSet referenceSet; if (s_snapshotCache.TryGetValue(finalOrDeclarationCompilation, out referenceSet)) { solution.Workspace.LogTestMessage($"Found already cached metadata in {nameof(s_snapshotCache)} for the exact compilation"); reference = referenceSet.GetMetadataReference(finalOrDeclarationCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes); return(true); } // okay, now use version based cache that can live multiple compilation as long as there is no semantic changes. // get one for the branch if (TryGetReferenceFromBranch(solution.BranchId, projectReference, finalOrDeclarationCompilation, version, out reference)) { solution.Workspace.LogTestMessage($"Found already cached metadata for the branch and version {version}"); return(true); } // see whether we can use primary branch one var primaryBranchId = solution.Workspace.PrimaryBranchId; if (solution.BranchId != primaryBranchId && TryGetReferenceFromBranch(primaryBranchId, projectReference, finalOrDeclarationCompilation, version, out reference)) { solution.Workspace.LogTestMessage($"Found already cached metadata for the primary branch and version {version}"); return(true); } // noop, we don't have any reference = null; return(false); }
public MetadataOnlyReferenceSet(VersionStamp version, MetadataOnlyImage image) { _version = version; _image = image; }
public bool TryGetTextVersion(out VersionStamp version) { version = _version; return(version != default(VersionStamp)); }
public TreeTextSource(ValueSource <SourceText> text, VersionStamp version, string filePath) { _lazyText = text; _version = version; _filePath = filePath; }
/// <summary> /// Adds a document to the workspace. /// </summary> public DocumentId AddDocument(ProjectId projectId, string name, string text) { if (projectId == null) { throw new ArgumentNullException("projectId"); } if (name == null) { throw new ArgumentNullException("name"); } if (text == null) { throw new ArgumentNullException("text"); } var id = DocumentId.CreateNewId(projectId); this.AddDocument( DocumentInfo.Create(id, name, loader: TextLoader.From(TextAndVersion.Create(SourceText.From(text), VersionStamp.Create())))); return(id); }
internal SolutionInfo WithVersion(VersionStamp version) { return(With(attributes: new SolutionAttributes(Attributes.Id, version, Attributes.FilePath))); }
public SolutionAttributes(SolutionId id, VersionStamp version, string filePath) { Id = id ?? throw new ArgumentNullException(nameof(id)); Version = version; FilePath = filePath; }
public SolutionAttributes WithVersion(VersionStamp versionStamp) { return(new SolutionAttributes(Id, versionStamp, FilePath)); }
/// <summary> /// Creates a new solution instance that includes a project with the specified language and names. /// </summary> public Solution AddProject(ProjectId projectId, string name, string assemblyName, string language) { return(this.AddProject(ProjectInfo.Create(projectId, VersionStamp.Create(), name, assemblyName, language))); }
private static TreeAndVersion MakeNewTreeAndVersion(SyntaxTree oldTree, SourceText oldText, VersionStamp oldVersion, SyntaxTree newTree, SourceText newText, VersionStamp newVersion) { var topLevelChanged = TopLevelChanged(oldTree, oldText, newTree, newText); var version = topLevelChanged ? newVersion : oldVersion; return(TreeAndVersion.Create(newTree, version)); }
private static bool TryGetReferenceFromBranch( BranchId branchId, ProjectReference projectReference, Compilation finalOrDeclarationCompilation, VersionStamp version, out MetadataReference reference) { // get map for the branch var mapFromBranch = s_cache.GetValue(branchId, s_createReferenceSetMap); // if we have one, return it MetadataOnlyReferenceSet referenceSet; if (mapFromBranch.TryGetValue(projectReference.ProjectId, out referenceSet) && (version == VersionStamp.Default || referenceSet.Version == version)) { // record it to snapshot based cache. var newReferenceSet = s_snapshotCache.GetValue(finalOrDeclarationCompilation, _ => referenceSet); reference = newReferenceSet.GetMetadataReference(finalOrDeclarationCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes); return(true); } reference = null; return(false); }
public ProjectInfo WithVersion(VersionStamp version) { return(this.With(version: version)); }
internal static MetadataReference GetOrBuildReference( SolutionState solution, ProjectReference projectReference, Compilation finalCompilation, VersionStamp version, CancellationToken cancellationToken) { solution.Workspace.LogTestMessage($"Looking to see if we already have a skeleton assembly for {projectReference.ProjectId} before we build one..."); MetadataReference reference; if (TryGetReference(solution, projectReference, finalCompilation, version, out reference)) { solution.Workspace.LogTestMessage($"A reference was found {projectReference.ProjectId} so we're skipping the build."); return(reference); } // okay, we don't have one. so create one now. // first, prepare image // * NOTE * image is cancellable, do not create it inside of conditional weak table. var service = solution.Workspace.Services.GetService <ITemporaryStorageService>(); var image = MetadataOnlyImage.Create(solution.Workspace, service, finalCompilation, cancellationToken); if (image.IsEmpty) { // unfortunately, we couldn't create one. do best effort if (TryGetReference(solution, projectReference, finalCompilation, VersionStamp.Default, out reference)) { solution.Workspace.LogTestMessage($"We failed to create metadata so we're using the one we just found from an earlier version."); // we have one from previous compilation!!, it might be out-of-date big time, but better than nothing. // re-use it return(reference); } } // okay, proceed with whatever image we have // now, remove existing set var mapFromBranch = s_cache.GetValue(solution.BranchId, s_createReferenceSetMap); mapFromBranch.Remove(projectReference.ProjectId); // create new one var newReferenceSet = new MetadataOnlyReferenceSet(version, image); var referenceSet = s_snapshotCache.GetValue(finalCompilation, _ => newReferenceSet); if (newReferenceSet != referenceSet) { // someone else has beaten us. // let image go eagerly. otherwise, finalizer in temporary storage will take care of it image.Cleanup(); // return new reference return(referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes)); } else { solution.Workspace.LogTestMessage($"Successfully stored the metadata generated for {projectReference.ProjectId}"); } // record it to version based cache as well. snapshot cache always has a higher priority. we don't need to check returned set here // since snapshot based cache will take care of same compilation for us. mapFromBranch.GetValue(projectReference.ProjectId, _ => referenceSet); // return new reference return(referenceSet.GetMetadataReference(finalCompilation, projectReference.Aliases, projectReference.EmbedInteropTypes)); }
internal TextContainerLoader(SourceTextContainer container, VersionStamp version, string filePath) { _container = container; _version = version; _filePath = filePath; }
/// <summary> /// Create a <see cref="ProjectInfo"/> structure initialized from a compilers command line arguments. /// </summary> public static ProjectInfo CreateProjectInfo(string projectName, string language, IEnumerable <string> commandLineArgs, string projectDirectory, Workspace workspace = null) { // TODO (tomat): the method may throw all sorts of exceptions. var tmpWorkspace = workspace ?? new AdhocWorkspace(DesktopMefHostServices.DefaultServices); var languageServices = tmpWorkspace.Services.GetLanguageServices(language); if (languageServices == null) { throw new ArgumentException(WorkspacesResources.Unrecognized_language_name); } var commandLineParser = languageServices.GetRequiredService <ICommandLineParserService>(); var commandLineArguments = commandLineParser.Parse(commandLineArgs, projectDirectory, isInteractive: false, sdkDirectory: RuntimeEnvironment.GetRuntimeDirectory()); var metadataService = tmpWorkspace.Services.GetRequiredService <IMetadataService>(); // we only support file paths in /r command line arguments var relativePathResolver = new RelativePathResolver(commandLineArguments.ReferencePaths, commandLineArguments.BaseDirectory); var commandLineMetadataReferenceResolver = new WorkspaceMetadataFileReferenceResolver( metadataService, relativePathResolver); var analyzerLoader = tmpWorkspace.Services.GetRequiredService <IAnalyzerService>().GetLoader(); var xmlFileResolver = new XmlFileResolver(commandLineArguments.BaseDirectory); var strongNameProvider = new DesktopStrongNameProvider(commandLineArguments.KeyFileSearchPaths); // resolve all metadata references. var boundMetadataReferences = commandLineArguments.ResolveMetadataReferences(commandLineMetadataReferenceResolver); var unresolvedMetadataReferences = boundMetadataReferences.FirstOrDefault(r => r is UnresolvedMetadataReference); if (unresolvedMetadataReferences != null) { throw new ArgumentException(string.Format(WorkspacesResources.Can_t_resolve_metadata_reference_colon_0, ((UnresolvedMetadataReference)unresolvedMetadataReferences).Reference)); } // resolve all analyzer references. foreach (var path in commandLineArguments.AnalyzerReferences.Select(r => r.FilePath)) { analyzerLoader.AddDependencyLocation(relativePathResolver.ResolvePath(path, baseFilePath: null)); } var boundAnalyzerReferences = commandLineArguments.ResolveAnalyzerReferences(analyzerLoader); var unresolvedAnalyzerReferences = boundAnalyzerReferences.FirstOrDefault(r => r is UnresolvedAnalyzerReference); if (unresolvedAnalyzerReferences != null) { throw new ArgumentException(string.Format(WorkspacesResources.Can_t_resolve_analyzer_reference_colon_0, ((UnresolvedAnalyzerReference)unresolvedAnalyzerReferences).Display)); } AssemblyIdentityComparer assemblyIdentityComparer; if (commandLineArguments.AppConfigPath != null) { try { using var appConfigStream = new FileStream(commandLineArguments.AppConfigPath, FileMode.Open, FileAccess.Read); assemblyIdentityComparer = DesktopAssemblyIdentityComparer.LoadFromXml(appConfigStream); } catch (Exception e) { throw new ArgumentException(string.Format(WorkspacesResources.An_error_occurred_while_reading_the_specified_configuration_file_colon_0, e.Message)); } } else { assemblyIdentityComparer = DesktopAssemblyIdentityComparer.Default; } var projectId = ProjectId.CreateNewId(debugName: projectName); // construct file infos var docs = new List <DocumentInfo>(); foreach (var fileArg in commandLineArguments.SourceFiles) { var absolutePath = Path.IsPathRooted(fileArg.Path) || string.IsNullOrEmpty(projectDirectory) ? Path.GetFullPath(fileArg.Path) : Path.GetFullPath(Path.Combine(projectDirectory, fileArg.Path)); var relativePath = PathUtilities.GetRelativePath(projectDirectory, absolutePath); var isWithinProject = PathUtilities.IsChildPath(projectDirectory, absolutePath); var folderRoot = isWithinProject ? Path.GetDirectoryName(relativePath) : ""; var folders = isWithinProject ? GetFolders(relativePath) : null; var name = Path.GetFileName(relativePath); var id = DocumentId.CreateNewId(projectId, absolutePath); var doc = DocumentInfo.Create( id: id, name: name, folders: folders, sourceCodeKind: fileArg.IsScript ? SourceCodeKind.Script : SourceCodeKind.Regular, loader: new FileTextLoader(absolutePath, commandLineArguments.Encoding), filePath: absolutePath); docs.Add(doc); } // construct file infos for additional files. var additionalDocs = new List <DocumentInfo>(); foreach (var fileArg in commandLineArguments.AdditionalFiles) { var absolutePath = Path.IsPathRooted(fileArg.Path) || string.IsNullOrEmpty(projectDirectory) ? Path.GetFullPath(fileArg.Path) : Path.GetFullPath(Path.Combine(projectDirectory, fileArg.Path)); var relativePath = PathUtilities.GetRelativePath(projectDirectory, absolutePath); var isWithinProject = PathUtilities.IsChildPath(projectDirectory, absolutePath); var folderRoot = isWithinProject ? Path.GetDirectoryName(relativePath) : ""; var folders = isWithinProject ? GetFolders(relativePath) : null; var name = Path.GetFileName(relativePath); var id = DocumentId.CreateNewId(projectId, absolutePath); var doc = DocumentInfo.Create( id: id, name: name, folders: folders, sourceCodeKind: SourceCodeKind.Regular, loader: new FileTextLoader(absolutePath, commandLineArguments.Encoding), filePath: absolutePath); additionalDocs.Add(doc); } // If /out is not specified and the project is a console app the csc.exe finds out the Main method // and names the compilation after the file that contains it. We don't want to create a compilation, // bind Mains etc. here. Besides the msbuild always includes /out in the command line it produces. // So if we don't have the /out argument we name the compilation "<anonymous>". string assemblyName = (commandLineArguments.OutputFileName != null) ? Path.GetFileNameWithoutExtension(commandLineArguments.OutputFileName) : "<anonymous>"; // TODO (tomat): what should be the assemblyName when compiling a netmodule? Should it be /moduleassemblyname var projectInfo = ProjectInfo.Create( projectId, VersionStamp.Create(), projectName, assemblyName, language: language, compilationOptions: commandLineArguments.CompilationOptions .WithXmlReferenceResolver(xmlFileResolver) .WithAssemblyIdentityComparer(assemblyIdentityComparer) .WithStrongNameProvider(strongNameProvider) // TODO (https://github.com/dotnet/roslyn/issues/4967): .WithMetadataReferenceResolver(new WorkspaceMetadataFileReferenceResolver(metadataService, new RelativePathResolver(ImmutableArray <string> .Empty, projectDirectory))), parseOptions: commandLineArguments.ParseOptions, documents: docs, additionalDocuments: additionalDocs, metadataReferences: boundMetadataReferences, analyzerReferences: boundAnalyzerReferences); return(projectInfo); }
private static TextAndVersion GetProperTextAndVersion(SourceText oldText, SourceText newText, VersionStamp version, string filePath) { // if the supplied text is the same as the previous text, then also use same version // otherwise use new version return oldText.ContentEquals(newText) ? TextAndVersion.Create(newText, version, filePath) : TextAndVersion.Create(newText, version.GetNewerVersion(), filePath); }
private static async Task <VersionStamp> ComputeTopLevelChangeTextVersionAsync(VersionStamp oldVersion, TextDocumentState newDocument, CancellationToken cancellationToken) { var newVersion = await newDocument.GetTopLevelChangeTextVersionAsync(cancellationToken).ConfigureAwait(false); return(newVersion.GetNewerVersion(oldVersion)); }
/// <summary> /// Gets the version of the document's text if it is already loaded and available. /// </summary> public bool TryGetTextVersion(out VersionStamp version) { return(this.state.TryGetTextVersion(out version)); }
private TreeAndVersion(SyntaxTree tree, VersionStamp version) { this.Tree = tree; this.Version = version; }
/// <summary> /// Gets the version of the document's text if it is already loaded and available. /// </summary> public bool TryGetTextVersion(out VersionStamp version) { return(this.GetDocumentState().TryGetTextVersion(out version)); }