Пример #1
0
        private SourceSpan?Find(ReferencesPool pool, SiliconStudio.Shaders.Ast.SourceLocation location)
        {
            foreach (var methodRef in pool.MethodsReferences)
            {
                foreach (var expression in methodRef.Value)
                {
                    if (IsExpressionMatching(expression, location))
                    {
                        return(methodRef.Key.Span);
                    }
                }
            }

            foreach (var variableRef in pool.VariablesReferences)
            {
                foreach (var expression in variableRef.Value)
                {
                    if (IsExpressionMatching(expression.Expression, location))
                    {
                        return(variableRef.Key.Span);
                    }
                }
            }
            return(null);
        }
Пример #2
0
        private bool IsExpressionMatching(Node astNode, SiliconStudio.Shaders.Ast.SourceLocation location)
        {
            var span        = astNode.Span;
            var startColumn = span.Location.Column;
            var endColumn   = startColumn + span.Length;

            if (astNode.Span.Location.Line == location.Line && location.Column >= startColumn)
            {
                if (location.Column >= startColumn && location.Column <= endColumn)
                {
                    return(true);
                }
            }
            return(false);
        }
Пример #3
0
        /// <summary>
        /// Analyzes the shader source code and go to definition.
        /// </summary>
        /// <param name="shaderSource">The shader source.</param>
        /// <param name="location">The location.</param>
        /// <param name="shaderDirectories">The shader directories.</param>
        /// <returns>ShaderNavigationResult.</returns>
        /// <exception cref="System.ArgumentNullException">shaderSource</exception>
        /// <exception cref="System.ArgumentException">Expecting a FileSource location;location</exception>
        public ShaderNavigationResult AnalyzeAndGoToDefinition(string shaderSource, SiliconStudio.Shaders.Ast.SourceLocation location, List <string> shaderDirectories)
        {
            if (shaderSource == null)
            {
                throw new ArgumentNullException("shaderSource");
            }
            var navigationResult = new ShaderNavigationResult();

            if (location.FileSource == null)
            {
                throw new ArgumentException("Expecting a FileSource location", "location");
            }

            try
            {
                if (location.FileSource.EndsWith(".xksl", StringComparison.CurrentCultureIgnoreCase))
                {
                    AnalyzeAndGoToDefinition(shaderSource, location, shaderDirectories, navigationResult);
                }

                // If any of the messages have empty filesource, add a default filesource
                foreach (var message in navigationResult.Messages.Messages)
                {
                    if (string.IsNullOrWhiteSpace(message.Span.Location.FileSource))
                    {
                        message.Span.Location.FileSource = location.FileSource;
                    }
                }
            }
            catch (Exception ex)
            {
                navigationResult.Messages.Error(MessageCode.ErrorUnexpectedException, GetSpan(location), ex);
            }

            return(navigationResult);
        }
Пример #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SourceSpan"/> struct.
 /// </summary>
 /// <param name="location">
 /// The location.
 /// </param>
 /// <param name="length">
 /// The length.
 /// </param>
 public SourceSpan(SourceLocation location, int length)
 {
     Location = location;
     Length = length;
 }
Пример #5
0
 public static Irony.Parsing.SourceLocation Convert(SourceLocation sourceLocation)
 {
     return new Irony.Parsing.SourceLocation(sourceLocation.Position, sourceLocation.Line, sourceLocation.Column, sourceLocation.FileSource);
 }
Пример #6
0
        private void AnalyzeAndGoToDefinition(string shaderSource, SiliconStudio.Shaders.Ast.SourceLocation location, List <string> shaderDirectories, ShaderNavigationResult result)
        {
            // We are not using the storage when loading shaders from VS but directly the filesystem
            var mixer = new ShaderMixinParser(null);

            mixer.SourceManager.UseFileSystem  = true;
            mixer.AllowNonInstantiatedGenerics = true;
            mixer.SourceManager.LookupDirectoryList.AddRange(shaderDirectories);

            var shaderSourceName = Path.GetFileNameWithoutExtension(location.FileSource);

            mixer.SourceManager.AddShaderSource(shaderSourceName, shaderSource, location.FileSource);

            var mixinSource = new ShaderMixinSource();

            mixinSource.Mixins.Add(new ShaderClassSource(shaderSourceName));

            ShaderMixinParsingResult  parsingResult;
            HashSet <ModuleMixinInfo> moduleMixins;
            var mixerResult = mixer.ParseAndAnalyze(mixinSource, null, out parsingResult, out moduleMixins);

            // Copy shader analysis to result
            parsingResult.CopyTo(result.Messages);

            if (mixerResult == null)
            {
                return;
            }

            var mixin = mixerResult.MixinInfos.FirstOrDefault(item => item.MixinName == shaderSourceName);

            if (mixin == null)
            {
                result.Messages.Error(ErrorMixinNotFound, GetSpan(location), shaderSourceName);
                return;
            }

            // If first line, first column, this is not a go to definition but only parsing request, so return directly
            if (location.Line == 1 && location.Column == 1)
            {
                return;
            }

            // var ast = mixin.MixinAst;

            var parsingInfo = mixin.Mixin.ParsingInfo;

            var pools = new List <ReferencesPool>
            {
                parsingInfo.ClassReferences,
                parsingInfo.StaticReferences,
                parsingInfo.ExternReferences,
                parsingInfo.StageInitReferences,
            };

            foreach (var pool in pools)
            {
                var span = Find(pool, location);
                if (span.HasValue)
                {
                    result.DefinitionLocation = span.Value;
                    return;
                }
            }

            // Else Try to find from remaining navigable nodes
            foreach (var node in parsingInfo.NavigableNodes)
            {
                if (IsExpressionMatching(node, location))
                {
                    var typeReferencer = node as ITypeInferencer;
                    if (typeReferencer != null && typeReferencer.TypeInference != null && typeReferencer.TypeInference.Declaration != null)
                    {
                        var declarationNode = (Node)typeReferencer.TypeInference.Declaration;
                        result.DefinitionLocation = declarationNode.Span;
                        break;
                    }
                }
            }
        }
Пример #7
0
 private static SourceSpan GetSpan(SourceLocation location)
 {
     return new SourceSpan(new SourceLocation(location.FileSource, 0, 1, 1), 1);
 }
Пример #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SourceSpan"/> struct.
 /// </summary>
 /// <param name="location">
 /// The location.
 /// </param>
 /// <param name="length">
 /// The length.
 /// </param>
 public SourceSpan(SourceLocation location, int length)
 {
     Location = location;
     Length   = length;
 }