public LockFile CreateLockFile()

in src/NuGet.Core/NuGet.Commands/RestoreCommand/LockFileBuilder.cs [39:290]


        public LockFile CreateLockFile(LockFile previousLockFile,
            PackageSpec project,
            IEnumerable<RestoreTargetGraph> targetGraphs,
            IReadOnlyList<NuGetv3LocalRepository> localRepositories,
            RemoteWalkContext context,
            LockFileBuilderCache lockFileBuilderCache)
        {
            var lockFile = new LockFile()
            {
                Version = _lockFileVersion
            };

            var previousLibraries = previousLockFile?.Libraries.ToDictionary(l => ValueTuple.Create(l.Name, l.Version));

            if (project.RestoreMetadata?.ProjectStyle == ProjectStyle.PackageReference)
            {
                AddProjectFileDependenciesForPackageReference(project, lockFile, targetGraphs.AsList());
            }

            // Record all libraries used
            var libraryItems = targetGraphs
                .SelectMany(g => g.Flattened) // All GraphItem<RemoteResolveResult> resolved in the graph.
                .Distinct(GraphItemKeyComparer<RemoteResolveResult>.Instance) // Distinct list of GraphItems. Two items are equal only if the itmes' Keys are equal.
                .OrderBy(x => x.Data.Match.Library);
            foreach (var item in libraryItems)
            {
                var library = item.Data.Match.Library;

                if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase))
                {
                    // Do not include the project itself as a library.
                    continue;
                }

                if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject)
                {
                    // Project
                    var localMatch = (LocalMatch)item.Data.Match;
                    string path = null;
                    string msBuildProject = null;

                    // Set the relative path if a path exists
                    // For projects without project.json this will be empty
                    if (!string.IsNullOrEmpty(localMatch.LocalLibrary.Path))
                    {
                        path = PathUtility.GetRelativePath(
                            project.FilePath,
                            localMatch.LocalLibrary.Path,
                            '/');
                    }

                    // The msbuild project path if it exists
                    object msbuildPath;
                    if (localMatch.LocalLibrary.Items.TryGetValue(KnownLibraryProperties.MSBuildProjectPath, out msbuildPath))
                    {
                        var msbuildRelativePath = PathUtility.GetRelativePath(
                            project.FilePath,
                            (string)msbuildPath,
                            '/');

                        msBuildProject = msbuildRelativePath;
                    }

                    var projectLib = new LockFileLibrary()
                    {
                        MSBuildProject = msBuildProject,
                        Name = library.Name,
                        Path = path,
                        Version = library.Version,
                        Type = LibraryType.Project,
                    };

                    lockFile.Libraries.Add(projectLib);
                }
                else if (library.Type == LibraryType.Package)
                {
                    // Packages
                    var packageInfo = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version);

                    // Add the library if it was resolved, unresolved packages are not added to the assets file.
                    if (packageInfo != null)
                    {
                        var package = packageInfo.Package;
                        var resolver = packageInfo.Repository.PathResolver;

                        var sha512 = package.Sha512;
                        var path = PathUtility.GetPathWithForwardSlashes(resolver.GetPackageDirectory(package.Id, package.Version));
                        LockFileLibrary lockFileLib = null;
                        LockFileLibrary previousLibrary = null;

                        if (previousLibraries?.TryGetValue(ValueTuple.Create(package.Id, package.Version), out previousLibrary) == true)
                        {
                            // Check that the previous library is still valid
                            if (previousLibrary != null
                                && StringComparer.Ordinal.Equals(path, previousLibrary.Path)
                                && StringComparer.Ordinal.Equals(sha512, previousLibrary.Sha512))
                            {
                                // When deciding whether the lock file has changed,
                                // we compare the new lock file to the previous (in-memory) lock file.
                                lockFileLib = previousLibrary;
                            }
                        }

                        // Create a new lock file library if one doesn't exist already.
                        if (lockFileLib == null)
                        {
                            lockFileLib = CreateLockFileLibrary(package, sha512, path);
                        }

                        // Create a new lock file library
                        lockFile.Libraries.Add(lockFileLib);
                    }
                }
            }

            Dictionary<ValueTuple<string, NuGetVersion>, LockFileLibrary> libraries = EnsureUniqueLockFileLibraries(lockFile);

            var librariesWithWarnings = new HashSet<LibraryIdentity>();

            var rootProjectStyle = project.RestoreMetadata?.ProjectStyle ?? ProjectStyle.Unknown;

            // Add the targets
            foreach (var targetGraph in targetGraphs
                .OrderBy(graph => graph.Framework.ToString(), StringComparer.Ordinal)
                .ThenBy(graph => graph.RuntimeIdentifier, StringComparer.Ordinal))
            {
                var target = new LockFileTarget
                {
                    TargetFramework = targetGraph.Framework,
                    RuntimeIdentifier = targetGraph.RuntimeIdentifier,
                    TargetAlias = targetGraph.TargetAlias,
                };

                var flattenedFlags = IncludeFlagUtils.FlattenDependencyTypes(_includeFlagGraphs, project, targetGraph);

                // Check if warnings should be displayed for the current framework.
                var tfi = project.GetTargetFramework(targetGraph.Framework);

                bool warnForImportsOnGraph = tfi.Warn
                    && (target.TargetFramework is FallbackFramework
                        || target.TargetFramework is AssetTargetFallbackFramework);

                foreach (var graphItem in targetGraph.Flattened.OrderBy(x => x.Key))
                {
                    var library = graphItem.Key;

                    // include flags
                    LibraryIncludeFlags includeFlags;
                    if (!flattenedFlags.TryGetValue(library.Name, out includeFlags))
                    {
                        includeFlags = ~LibraryIncludeFlags.ContentFiles;
                    }

                    if (library.Type == LibraryType.Project || library.Type == LibraryType.ExternalProject)
                    {
                        if (project.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            // Do not include the project itself as a library.
                            continue;
                        }

                        var projectLib = LockFileUtils.CreateLockFileTargetProject(
                            graphItem,
                            library,
                            includeFlags,
                            targetGraph,
                            rootProjectStyle);

                        target.Libraries.Add(projectLib);
                    }
                    else if (library.Type == LibraryType.Package)
                    {
                        var packageInfo = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, library.Name, library.Version);

                        if (packageInfo == null)
                        {
                            continue;
                        }

                        var package = packageInfo.Package;
                        var libraryDependency = tfi.Dependencies.FirstOrDefault(e => e.Name.Equals(library.Name, StringComparison.OrdinalIgnoreCase));

                        (LockFileTargetLibrary targetLibrary, bool usedFallbackFramework) = LockFileUtils.CreateLockFileTargetLibrary(
                            libraryDependency?.Aliases,
                            libraries[ValueTuple.Create(library.Name, library.Version)],
                            package,
                            targetGraph,
                            dependencyType: includeFlags,
                            targetFrameworkOverride: null,
                            dependencies: graphItem.Data.Dependencies,
                            cache: lockFileBuilderCache);

                        target.Libraries.Add(targetLibrary);

                        // Log warnings if the target library used the fallback framework
                        if (warnForImportsOnGraph && !librariesWithWarnings.Contains(library))
                        {
                            if (target.TargetFramework is FallbackFramework)
                            {
                                // PackageTargetFallback works different from AssetTargetFallback so the warning logic for PTF cannot be optimized.
                                var nonFallbackFramework = new NuGetFramework(target.TargetFramework);

                                var targetLibraryWithoutFallback = LockFileUtils.CreateLockFileTargetLibrary(
                                    libraryDependency?.Aliases,
                                    libraries[ValueTuple.Create(library.Name, library.Version)],
                                    package,
                                    targetGraph,
                                    targetFrameworkOverride: nonFallbackFramework,
                                    dependencyType: includeFlags,
                                    dependencies: graphItem.Data.Dependencies,
                                    cache: lockFileBuilderCache);
                                usedFallbackFramework = !targetLibrary.Equals(targetLibraryWithoutFallback);
                            }

                            if (usedFallbackFramework)
                            {
                                var libraryName = DiagnosticUtility.FormatIdentity(library);

                                var message = string.Format(CultureInfo.CurrentCulture,
                                    Strings.Log_ImportsFallbackWarning,
                                    libraryName,
                                    GetFallbackFrameworkString(target.TargetFramework),
                                    new NuGetFramework(target.TargetFramework));

                                var logMessage = RestoreLogMessage.CreateWarning(
                                    NuGetLogCode.NU1701,
                                    message,
                                    library.Name,
                                    targetGraph.TargetGraphName);

                                _logger.Log(logMessage);

                                // only log the warning once per library
                                librariesWithWarnings.Add(library);
                            }
                        }
                    }
                }

                EnsureUniqueLockFileTargetLibraries(target);
                lockFile.Targets.Add(target);
            }

            PopulatePackageFolders(localRepositories.Select(repo => repo.RepositoryRoot).Distinct(), lockFile);

            AddCentralTransitiveDependencyGroupsForPackageReference(project, lockFile, targetGraphs, _logger);

            // Add the original package spec to the lock file.
            lockFile.PackageSpec = project;

            return lockFile;
        }