public CppInclusionContextResult CreateInclusionContextResult(CppGlobalSymbolCache cache,
                                                                      CppFileLocation rootFile,
                                                                      FileProcessingOptions options, long cacheVersion, Lifetime lifetime)
        {
            var locationTracker = cache.Solution.GetComponent <InjectedHlslFileLocationTracker>();

            if (!locationTracker.IsValid(rootFile))
            {
                return(CppInclusionContextResult.Fail(CppInclusionContextResult.Status.UNSUITABLE_PROJECT_FILE));
            }


            var properties = new CppCompilationProperties()
            {
                LanguageKind = CppLanguageKind.HLSL, ClrSupport = VCXCompileAsManagedOptions.ManagedNotSet,
            };

            var cgIncludeFolder =
                CgIncludeDirectoryTracker.GetCgIncludeFolderPath(cache.Solution.GetComponent <UnityVersion>());

            if (!cgIncludeFolder.IsEmpty)
            {
                properties.IncludePaths.Add(cgIncludeFolder);
            }
            properties.IncludePaths.Add(cache.Solution.SolutionDirectory);

            return(CreateInclusionContextResult(cache, rootFile, options, properties, null, cacheVersion, lifetime));
        }
Пример #2
0
        public CppInclusionContextResult CreateInclusionContextResult(CppGlobalSymbolCache cache,
                                                                      CppFileLocation rootFile,
                                                                      FileProcessingOptions options, long cacheVersion, Lifetime lifetime)
        {
            var locationTracker = cache.Solution.GetComponent <ShaderLabCppFileLocationTracker>();

            if (!locationTracker.IsValid(rootFile))
            {
                return(CppInclusionContextResult.Fail(CppInclusionContextResult.Status.UNSUITABLE_PROJECT_FILE));
            }


            var properties = new CppCompilationProperties()
            {
                LanguageKind = CppLanguageKind.HLSL, ClrSupport = VCXCompileAsManagedOptions.ManagedNotSet,
            };

            var cgIncludeFolder =
                CgIncludeDirectoryTracker.GetCgIncludeFolderPath(cache.Solution.GetComponent <UnityVersion>());

            if (!cgIncludeFolder.IsEmpty)
            {
                properties.IncludePaths.Add(cgIncludeFolder);
            }

            var shaderCache = cache.Solution.GetComponent <ShaderLabCppFileLocationTracker>();

            // TODO 1) is cache ready? what will happen under document transaction? check for bad moment?
            // TODO 2) what will happen under psi transaction? include in cache could be out-of date. Try use include quickfix when cginclude is after cgprogram where QF is used
            var includeLocation = shaderCache.GetIncludes(rootFile);

            return(InjectInclusionContextProviderUtil.CreateInclusionContextResult(cache, rootFile,
                                                                                   includeLocation, options, properties, null, cacheVersion, lifetime));
        }
        public CppFileLocation GetPreferredRootFile(CppFileLocation currentFile)
        {
            using (ReadLockCookie.Create())
            {
                var sourceFile = currentFile.GetRandomSourceFile(mySolution);

                if (myShaderContext.TryGetFromCache(sourceFile.GetLocation(), out var result))
                {
                    var path = myManager.TryGetProjectFile(result.Document)?.Location;
                    if (path != null)
                    {
                        var location = new CppFileLocation(new FileSystemPathWithRange(path, result.Range));
                        if (!myLocationTracker.Exists(location))
                        {
                            myLogger.Trace(
                                $"Reset context for {sourceFile.GetPersistentIdForLogging()}, because inject is not registered");
                            myShaderContext.RemoveFromCache(sourceFile.GetLocation());
                            return(CppFileLocation.EMPTY);
                        }

                        return(location);
                    }
                }
            }

            return(CppFileLocation.EMPTY);
        }
        public static CppInclusionContextResult CreateInclusionContextResult(
            CppGlobalSymbolCache cache,
            CppFileLocation rootFile,
            IEnumerable <CppFileLocation> includeLocations,
            FileProcessingOptions options,
            CppCompilationProperties compilationProperties,
            ISymbolScope symbolScope,
            long cacheVersion,
            Lifetime lifetime)
        {
            var languageDialect   = CppProjectConfigurationUtil.GetLanguageDialect(compilationProperties);
            var randomProjectFile = rootFile.GetRandomProjectFile(cache.Solution);
            var inclusionContext  = CppRootInclusionContext.Create(compilationProperties, randomProjectFile.GetProject(),
                                                                   randomProjectFile, cache, rootFile, options.File, languageDialect,
                                                                   cacheVersion, options.AllowPendingActions, options.CollectPPUsages, lifetime, symbolScope);
            var directory = randomProjectFile.Location.Directory;

            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("SHADER_API_D3D11"));
            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("__RESHARPER__"));
            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("INTERNAL_DATA= "));
            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("WorldReflectionVector(data,normal)=data.worldRefl"));
            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("WorldNormalVector(data,normal)=normal"));
            inclusionContext.PushInclude(rootFile, directory, false);
            foreach (CppFileLocation includeLocation in includeLocations)
            {
                if (includeLocation.IsValid() && !includeLocation.Equals(rootFile))
                {
                    cache.LookupAndProcessTableForFile(rootFile, includeLocation, options, inclusionContext, directory);
                }
            }
            inclusionContext.PopInclude(false);
            return(CppInclusionContextResult.Ok(inclusionContext));
        }
Пример #5
0
 protected override bool Exists(IPsiSourceFile sourceFile, CppFileLocation cppFileLocation)
 {
     if (Map.TryGetValue(sourceFile, out var result) &&
         result.Any(d =>
                    d.FileSystemPath == cppFileLocation.Location && d.Range == cppFileLocation.RootRange))
     {
         return(true);
     }
     return(false);
 }
        protected override CppFileLocation GetFileLocation(IPsiSourceFile sourceFile, ITreeNode originalNode)
        {
            var cppFileLocation = new CppFileLocation(sourceFile, originalNode.GetDocumentRange().TextRange);

            if (!sourceFile.GetSolution().GetComponent <ShaderLabCppFileLocationTracker>().IsSuitableLocation(sourceFile, cppFileLocation))
            {
                return(CppFileLocation.EMPTY);
            }

            return(cppFileLocation);
        }
Пример #7
0
        private ShaderContextData GetContextDataFor(CppFileLocation root)
        {
            var range = myShaderContextDataPresentationCache.GetRangeForShaderProgram(root.GetRandomSourceFile(mySolution), root.RootRange);

            if (!range.HasValue)
            {
                return(null);
            }

            var folderFullPath = root.Location.Parent;
            var folderPath     = folderFullPath.TryMakeRelativeTo(mySolution.SolutionDirectory);

            var folderHint = folderPath.FullPath.ShortenTextWithEllipsis(40);

            return(new ShaderContextData(root.Location.FullPath, root.Location.Name, folderHint, root.RootRange.StartOffset, root.RootRange.EndOffset, range.Value.startLine + 1));
        }
        public static CppInclusionContextResult CreateInclusionContextResult(
            CppGlobalSymbolCache cache,
            CppFileLocation rootFile,
            FileProcessingOptions options,
            CppCompilationProperties compilationProperties,
            ISymbolScope symbolScope,
            long cacheVersion,
            Lifetime lifetime)
        {
            var languageDialect   = CppProjectConfigurationUtil.GetLanguageDialect(compilationProperties);
            var randomProjectFile = rootFile.GetRandomProjectFile(cache.Solution);
            var inclusionContext  = CppRootInclusionContext.Create(compilationProperties, randomProjectFile.GetProject(),
                                                                   randomProjectFile, cache, rootFile, options.File, languageDialect,
                                                                   cacheVersion, options.AllowPendingActions, options.CollectPPUsages, lifetime, symbolScope);
            var directory = randomProjectFile.Location.Directory;

            var shaderCache = cache.Solution.GetComponent <InjectedHlslFileLocationTracker>();

            var(includes, defines) = shaderCache.GetProgramInfo(rootFile);

            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("SHADER_API_D3D11"));
            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("__RESHARPER__"));
            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("INTERNAL_DATA= "));
            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("WorldReflectionVector(data,normal)=data.worldRefl"));
            inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro("WorldNormalVector(data,normal)=normal"));

            foreach (var define in defines)
            {
                inclusionContext.ProcessDefine(CppPPDefineSymbol.ParsePredefinedMacro($"{define.Key}={define.Value}"));
            }

            // TODO 1) is cache ready? what will happen under document transaction? check for bad moment?
            // TODO 2) what will happen under psi transaction? include in cache could be out-of date. Try use include quickfix when cginclude is after cgprogram where QF is used


            inclusionContext.PushInclude(rootFile, directory, false);
            foreach (CppFileLocation includeLocation in includes)
            {
                if (includeLocation.IsValid() && !includeLocation.Equals(rootFile))
                {
                    cache.LookupAndProcessTableForFile(rootFile, includeLocation, options, inclusionContext, directory);
                }
            }
            inclusionContext.PopInclude(false);
            return(CppInclusionContextResult.Ok(inclusionContext));
        }
Пример #9
0
        public IEnumerable <CppFileLocation> GetIncludes(CppFileLocation cppFileLocation)
        {
            var sourceFile = cppFileLocation.GetRandomSourceFile(mySolution);
            var cgInclude  = GetCgIncludeLocation(sourceFile);

            if (!cgInclude.Equals(CppFileLocation.EMPTY))
            {
                yield return(cgInclude);
            }

            var cgIncludeFolder = CgIncludeDirectoryTracker.GetCgIncludeFolderPath(myUnityVersion);

            if (!cgIncludeFolder.ExistsDirectory)
            {
                yield break;
            }

            var range = cppFileLocation.RootRange;

            Assertion.Assert(range.IsValid, "range.IsValid");
            var program = sourceFile.GetDominantPsiFile <ShaderLabLanguage>()?.GetContainingNodeAt <ICgContent>(new TreeOffset(range.StartOffset));

            Assertion.Assert(program != null, "program != null");

            if (program?.Parent?.FirstChild is ICgProgramBlock)
            {
                var hlslSupport = cgIncludeFolder.Combine("HLSLSupport.cginc");
                if (hlslSupport.ExistsFile)
                {
                    yield return(new CppFileLocation(hlslSupport));
                }

                var variables = cgIncludeFolder.Combine("UnityShaderVariables.cginc");
                if (variables.ExistsFile)
                {
                    yield return(new CppFileLocation(variables));
                }
            }
        }
Пример #10
0
        public CppCompilationProperties GetCompilationProperties(IProject project, IProjectFile projectFile, CppFileLocation rootFile,
                                                                 CppGlobalSymbolCache globalCache)
        {
            if (project.IsUnityProject() && CppProjectFileType.ALL_HLSL_EXTENSIONS.Contains(rootFile.Location.ExtensionWithDot))
            {
                var properties = new CppCompilationProperties();
                properties.LanguageKind = CppLanguageKind.HLSL;
                var path = CgIncludeDirectoryTracker.GetCgIncludeFolderPath(myUnityVersion);
                if (!path.IsEmpty)
                {
                    properties.IncludePaths.Add(path);
                }

                return(properties);
            }

            return(null);
        }
Пример #11
0
        public ShaderContextHost(Lifetime lifetime, ISolution solution, IPsiFiles psiFiles,
                                 CppGlobalSymbolCache cppGlobalSymbolCache,
                                 ShaderContextCache shaderContextCache,
                                 ShaderContextDataPresentationCache shaderContextDataPresentationCache, ILogger logger,
                                 [CanBeNull] FrontendBackendHost frontendBackendHost = null,
                                 [CanBeNull] RiderDocumentHost documentHost          = null)
        {
            mySolution             = solution;
            myPsiFiles             = psiFiles;
            myCppGlobalSymbolCache = cppGlobalSymbolCache;
            myDocumentHost         = documentHost;
            myShaderContextCache   = shaderContextCache;
            myShaderContextDataPresentationCache = shaderContextDataPresentationCache;

            if (frontendBackendHost == null || documentHost == null)
            {
                return;
            }

            frontendBackendHost.Do(t =>
            {
                t.RequestShaderContexts.Set((lt, id) =>
                {
                    logger.Verbose("Requesting all shader context for file");
                    using (ReadLockCookie.Create())
                    {
                        var sourceFile = GetSourceFile(id);
                        if (sourceFile == null)
                        {
                            return(Rd.Tasks.RdTask <List <ShaderContextDataBase> > .Successful(
                                       new List <ShaderContextDataBase>()));
                        }
                        var task = new Rd.Tasks.RdTask <List <ShaderContextDataBase> >();
                        RequestShaderContexts(lt, sourceFile, task);

                        return(task);
                    }
                });

                t.ChangeContext.Advise(lifetime, c =>
                {
                    logger.Verbose("Setting new shader context for file");
                    using (ReadLockCookie.Create())
                    {
                        IPsiSourceFile sourceFile = GetSourceFile(c.Target);
                        if (sourceFile == null)
                        {
                            return;
                        }

                        var cppFileLocation = new CppFileLocation(
                            new FileSystemPathWithRange(FileSystemPath.Parse(c.Path), new TextRange(c.Start, c.End)));
                        shaderContextCache.SetContext(sourceFile, cppFileLocation);
                    }
                });

                t.SetAutoShaderContext.Advise(lifetime, id =>
                {
                    using (ReadLockCookie.Create())
                    {
                        IPsiSourceFile sourceFile = GetSourceFile(id);
                        if (sourceFile == null)
                        {
                            return;
                        }
                        shaderContextCache.SetContext(sourceFile, null);
                    }
                });

                t.RequestCurrentContext.Set((lt, id) =>
                {
                    logger.Verbose("Setting current context for file");
                    using (ReadLockCookie.Create())
                    {
                        var sourceFile = GetSourceFile(id);
                        if (sourceFile == null)
                        {
                            return(Rd.Tasks.RdTask <ShaderContextDataBase> .Successful(new AutoShaderContextData()));
                        }

                        var task = new Rd.Tasks.RdTask <ShaderContextDataBase>();
                        RequestCurrentContext(lt, sourceFile, task);
                        return(task);
                    }
                });
            });
        }
        public CppCompilationProperties GetCompilationProperties(IProject project, IProjectFile projectFile, CppFileLocation rootFile,
                                                                 CppGlobalSymbolCache globalCache)
        {
            if (project.IsUnityProject() && CppProjectFileType.ALL_HLSL_EXTENSIONS.Contains(rootFile.Location.ExtensionWithDot))
            {
                var properties = new CppCompilationProperties();
                properties.LanguageKind = CppLanguageKind.HLSL;
                var path = CgIncludeDirectoryTracker.GetCgIncludeFolderPath(myUnityVersion);
                if (!path.IsEmpty)
                {
                    properties.IncludePaths.Add(path);
                }

                properties.ForcedIncludes.Add(globalCache.Solution.SolutionDirectory.Combine(Utils.ShaderConfigFile).FullPath);

                properties.PredefinedMacros.Add(CppPPDefineSymbol.ParsePredefinedMacro("SHADER_API_D3D11"));
                properties.IncludePaths.Add(globalCache.Solution.SolutionDirectory);

                return(properties);
            }

            return(null);
        }
        public (IEnumerable <CppFileLocation> includeLocations, Dictionary <string, string> defines) GetProgramInfo(CppFileLocation cppFileLocation)
        {
            // PSI is not commited here
            // TODO: cpp global cache should calculate cache only when PSI for file with cpp injects is committed.

            var sourceFile = cppFileLocation.GetRandomSourceFile(mySolution);
            var range      = cppFileLocation.RootRange;

            Assertion.Assert(range.IsValid, "range.IsValid");

            var buffer = sourceFile.Document.Buffer;
            var type   = GetShaderProgramType(buffer, range.StartOffset);


            var defines  = GetDefinedMacroses(ProjectedBuffer.Create(buffer, range), out var isSurface);
            var includes = GetIncludes(sourceFile, type, isSurface);

            return(includes, defines);
        }
        public IEnumerable <CppFileLocation> GetIncludes(CppFileLocation cppFileLocation)
        {
            // PSI is not commited here
            // TODO: cpp global cache should calculate cache only when PSI for file with cpp injects is committed.

            var sourceFile = cppFileLocation.GetRandomSourceFile(mySolution);
            var range      = cppFileLocation.RootRange;

            Assertion.Assert(range.IsValid, "range.IsValid");

            var buffer      = sourceFile.Document.Buffer;
            var type        = GetShaderProgramType(buffer, range.StartOffset);
            var includeType = GetIncludeProgramType(type);

            yield return(new CppFileLocation(myCppExternalModule, mySolution.SolutionDirectory.Combine(Utils.ShaderConfigFile)));

            if (includeType != InjectedHlslProgramType.Uknown)
            {
                var includes = GetIncludesLocation(sourceFile, includeType);
                foreach (var include in includes)
                {
                    yield return(include);
                }
            }


            var cgIncludeFolder = CgIncludeDirectoryTracker.GetCgIncludeFolderPath(myUnityVersion);

            if (!cgIncludeFolder.ExistsDirectory)
            {
                yield break;
            }

            if (type == InjectedHlslProgramType.CGProgram)
            {
                var hlslSupport = cgIncludeFolder.Combine("HLSLSupport.cginc");
                if (hlslSupport.ExistsFile)
                {
                    yield return(new CppFileLocation(myCppExternalModule, hlslSupport));
                }

                var variables = cgIncludeFolder.Combine("UnityShaderVariables.cginc");
                if (variables.ExistsFile)
                {
                    yield return(new CppFileLocation(myCppExternalModule, variables));
                }
            }

            var lexer = CppLexer.Create(ProjectedBuffer.Create(buffer, range));

            lexer.Start();
            while (lexer.TokenType != null)
            {
                var tokenType = lexer.TokenType;
                if (tokenType is CppDirectiveTokenNodeType)
                {
                    lexer.Advance();
                    var context = lexer.GetTokenText().TrimStart();
                    if (context.StartsWith("surface"))
                    {
                        var unityCG = cgIncludeFolder.Combine("UnityCG.cginc");
                        if (unityCG.ExistsFile)
                        {
                            yield return(new CppFileLocation(myCppExternalModule, unityCG));
                        }

                        var lighting = cgIncludeFolder.Combine("Lighting.cginc");
                        if (lighting.ExistsFile)
                        {
                            yield return(new CppFileLocation(myCppExternalModule, lighting));
                        }

                        var unityPbsLighting = cgIncludeFolder.Combine("UnityPBSLighting.cginc");
                        if (unityPbsLighting.ExistsFile)
                        {
                            yield return(new CppFileLocation(myCppExternalModule, unityPbsLighting));
                        }

                        var autoLight = cgIncludeFolder.Combine("AutoLight.cginc");
                        if (autoLight.ExistsFile)
                        {
                            yield return(new CppFileLocation(myCppExternalModule, autoLight));
                        }
                        break;
                    }
                    // TODO: optimization if we found vertex/fragment/geometry/hull/domain?
                }
                lexer.Advance();
            }
        }
 public bool Exists(CppFileLocation cppFileLocation)
 {
     return(Exists(cppFileLocation.GetRandomSourceFile(mySolution), cppFileLocation));
 }