Exemple #1
0
        public override AuthoringScope ParseSource(ParseRequest req)
        {
            CMakeAuthoringScope scope = new CMakeAuthoringScope();

            if (!CMakeSource.IsCMakeFile(req.FileName))
            {
                // Don't do IntelliSense parsing for ordinary text files.
                return(scope);
            }
            CMakeSource source = (CMakeSource)GetSource(req.FileName);

            if (req.Sink.HiddenRegions)
            {
                req.Sink.ProcessHiddenRegions = true;
                List <TextSpan> regions = CMakeParsing.ParseForFunctionBodies(
                    source.GetLines());
                foreach (TextSpan textSpan in regions)
                {
                    req.Sink.AddHiddenRegion(textSpan);
                }
            }
            if (req.Sink.BraceMatching)
            {
                List <CMakeParsing.SpanPair> pairs = null;
                switch ((CMakeToken)req.TokenInfo.Token)
                {
                case CMakeToken.OpenParen:
                case CMakeToken.CloseParen:
                    pairs = CMakeParsing.ParseForParens(source.GetLines());
                    break;

                case CMakeToken.VariableStart:
                case CMakeToken.VariableStartEnv:
                case CMakeToken.VariableStartCache:
                case CMakeToken.VariableStartSetEnv:
                case CMakeToken.VariableEnd:
                    pairs = CMakeParsing.ParseForVariableBraces(source.GetLines(),
                                                                req.Line);
                    break;

                case CMakeToken.GeneratorStart:
                case CMakeToken.GeneratorEnd:
                    pairs = CMakeParsing.ParseForGeneratorBraces(source.GetLines(),
                                                                 req.Line);
                    break;
                }
                if (pairs != null)
                {
                    foreach (CMakeParsing.SpanPair pair in pairs)
                    {
                        req.Sink.MatchPair(pair.First, pair.Second, 0);
                    }
                }
            }
            if (req.Reason == ParseReason.MemberSelect ||
                req.Reason == ParseReason.MemberSelectAndHighlightBraces ||
                req.Reason == ParseReason.CompleteWord)
            {
                // Set an appropriate declarations object depending on the token that
                // triggered member selection.
                CMakeToken token = (CMakeToken)req.TokenInfo.Token;
                if (token == CMakeToken.String)
                {
                    // If the token is a string and the user has began to reference a
                    // variable inside the string, treat the string as if it was the
                    // appropriate type of variable start token and display member
                    // selection for variables.
                    string line      = source.GetLine(req.Line);
                    string tokenText = line.ExtractToken(req.TokenInfo);
                    if (tokenText.EndsWith("${"))
                    {
                        token = CMakeToken.VariableStart;
                    }
                    else if (tokenText.EndsWith("$ENV{"))
                    {
                        token = CMakeToken.VariableStartEnv;
                    }
                    else if (tokenText.EndsWith("$CACHE{"))
                    {
                        token = CMakeToken.VariableStartCache;
                    }
                }
                if (token == CMakeToken.VariableStart)
                {
                    List <string> vars = CMakeParsing.ParseForVariables(
                        source.GetLines(), req.Line);
                    CMakeVariableDeclarations decls = new CMakeVariableDeclarations(vars,
                                                                                    CMakeVariableType.Variable);
                    decls.AddItems(source.GetIncludeCacheVariables(),
                                   CMakeItemDeclarations.ItemType.Variable);
                    string functionName = CMakeParsing.ParseForCurrentFunction(
                        source.GetLines(), req.Line);
                    if (functionName != null)
                    {
                        List <string> paramNames = CMakeParsing.ParseForParameterNames(
                            source.GetLines(), functionName);
                        paramNames.Add("ARGN");
                        decls.AddItems(paramNames,
                                       CMakeItemDeclarations.ItemType.Variable);
                    }
                    scope.SetDeclarations(decls);
                }
                else if (token == CMakeToken.VariableStartEnv)
                {
                    List <string> vars = CMakeParsing.ParseForEnvVariables(
                        source.GetLines());
                    CMakeVariableDeclarations decls = new CMakeVariableDeclarations(vars,
                                                                                    CMakeVariableType.EnvVariable);
                    decls.AddItems(source.GetIncludeCacheEnvVariables(),
                                   CMakeItemDeclarations.ItemType.Variable);
                    scope.SetDeclarations(decls);
                }
                else if (token == CMakeToken.VariableStartCache)
                {
                    List <string> vars = CMakeParsing.ParseForCacheVariables(
                        source.GetLines());
                    CMakeVariableDeclarations decls = new CMakeVariableDeclarations(vars,
                                                                                    CMakeVariableType.CacheVariable);
                    decls.AddItems(source.GetIncludeCacheCacheVariables(),
                                   CMakeItemDeclarations.ItemType.Variable);
                    scope.SetDeclarations(decls);
                }
                else if (token == CMakeToken.Identifier)
                {
                    CMakeParsing.TokenData tokenData;
                    CMakeParsing.ParseForToken(source.GetLines(), req.Line,
                                               req.TokenInfo.StartIndex, out tokenData);
                    if (!tokenData.InParens)
                    {
                        CMakeItemDeclarations decls    = new CMakeItemDeclarations();
                        IEnumerable <string>  commands = CMakeKeywords.GetAllCommands(
                            CMakePackage.Instance.CMakeOptionPage.ShowDeprecated);
                        if (!CMakePackage.Instance.CMakeOptionPage.CommandsLower)
                        {
                            commands = commands.Select(x => x.ToUpper());
                        }
                        decls.AddItems(commands, CMakeItemDeclarations.ItemType.Command);
                        decls.AddItems(
                            CMakeParsing.ParseForFunctionNames(source.GetLines(), false),
                            CMakeItemDeclarations.ItemType.Function);
                        decls.AddItems(
                            CMakeParsing.ParseForFunctionNames(source.GetLines(), true),
                            CMakeItemDeclarations.ItemType.Macro);
                        decls.AddItems(source.GetIncludeCacheFunctions(),
                                       CMakeItemDeclarations.ItemType.Function);
                        decls.AddItems(source.GetIncludeCacheMacros(),
                                       CMakeItemDeclarations.ItemType.Macro);
                        scope.SetDeclarations(decls);
                    }
                    else
                    {
                        Declarations decls = CMakeDeclarationsFactory.CreateDeclarations(
                            tokenData.Command, req, source,
                            tokenData.ParameterIndex > 0 ? tokenData.PriorParameters : null);
                        scope.SetDeclarations(decls);
                    }
                }
                else if (token == CMakeToken.OpenParen)
                {
                    CMakeCommandId id = CMakeParsing.ParseForTriggerCommandId(
                        source.GetLines(), req.Line, req.TokenInfo.StartIndex);
                    Declarations decls = CMakeDeclarationsFactory.CreateDeclarations(
                        id, req, source);
                    scope.SetDeclarations(decls);
                }
                else if (token == CMakeToken.WhiteSpace)
                {
                    CMakeParsing.TokenData tokenData;
                    CMakeParsing.ParseForToken(source.GetLines(), req.Line,
                                               req.TokenInfo.StartIndex, out tokenData);
                    Declarations decls = CMakeDeclarationsFactory.CreateDeclarations(
                        tokenData.Command, req, source,
                        tokenData.ParameterIndex > 0 ? tokenData.PriorParameters : null);
                    scope.SetDeclarations(decls);
                }
                else if (token == CMakeToken.GeneratorStart)
                {
                    scope.SetDeclarations(new CMakeGeneratorDeclarations());
                }
            }
            else if (req.Reason == ParseReason.MethodTip)
            {
                CMakeParsing.ParameterInfoResult result =
                    CMakeParsing.ParseForParameterInfo(source.GetLines(), req.Line,
                                                       req.TokenInfo.EndIndex);
                if (result.CommandName != null && result.CommandSpan.HasValue)
                {
                    if (result.SubcommandName == null)
                    {
                        req.Sink.StartName(result.CommandSpan.Value, result.CommandName);
                    }
                    else
                    {
                        req.Sink.StartName(result.CommandSpan.Value,
                                           result.CommandSpan + "(" + result.SubcommandName);
                    }
                    if (result.BeginSpan.HasValue)
                    {
                        req.Sink.StartParameters(result.BeginSpan.Value);
                    }
                    foreach (TextSpan span in result.SeparatorSpans)
                    {
                        req.Sink.NextParameter(span);
                    }
                    if (result.EndSpan.HasValue)
                    {
                        req.Sink.EndParameters(result.EndSpan.Value);
                    }
                    CMakeCommandId id = CMakeKeywords.GetCommandId(result.CommandName);
                    if (id == CMakeCommandId.Unspecified)
                    {
                        // If it's a user-defined function or macro, parse to try to find
                        // its parameters.
                        List <string> parameters = CMakeParsing.ParseForParameterNames(
                            source.GetLines(), result.CommandName);
                        if (parameters == null)
                        {
                            parameters = source.GetParametersFromIncludeCache(
                                result.CommandName);
                        }
                        if (parameters != null)
                        {
                            scope.SetMethods(new CMakeUserMethods(result.CommandName,
                                                                  parameters));
                        }
                    }
                    else
                    {
                        scope.SetMethods(CMakeMethods.GetCommandParameters(id,
                                                                           result.SubcommandName));
                    }
                }
            }
            else if (req.Reason == ParseReason.Goto)
            {
                scope.SetLines(source.GetLines());
                scope.SetFileName(req.FileName);
            }
            else if (req.Reason == ParseReason.QuickInfo)
            {
                scope.SetLines(source.GetLines());
            }
            else if (req.Reason == ParseReason.Check)
            {
                foreach (ParseForErrorMethod method in _parseForErrorMethods)
                {
                    List <CMakeErrorInfo> info = method(source.GetLines());
                    foreach (CMakeErrorInfo item in info)
                    {
                        CMakeError err = item.ErrorCode;
                        if (_errorStrings.ContainsKey(err) &&
                            (!_enabledMethods.ContainsKey(err) || _enabledMethods[err]()))
                        {
                            req.Sink.AddError(req.FileName, _errorStrings[err], item.Span,
                                              item.Warning ? Severity.Warning : Severity.Error);
                        }
                    }
                }
                if (CMakePackage.Instance.CMakeOptionPage.ParseIncludedFiles)
                {
                    source.BuildIncludeCache(source.GetLines());
                    source.UpdateIncludeCache();
                    source.PruneIncludeCache();
                }
                else
                {
                    source.ClearIncludeCache();
                }
            }
            return(scope);
        }
 public override AuthoringScope ParseSource(ParseRequest req)
 {
     CMakeAuthoringScope scope = new CMakeAuthoringScope();
     if (!CMakeSource.IsCMakeFile(req.FileName))
     {
         // Don't do IntelliSense parsing for ordinary text files.
         return scope;
     }
     CMakeSource source = (CMakeSource)GetSource(req.FileName);
     if (req.Sink.HiddenRegions)
     {
         req.Sink.ProcessHiddenRegions = true;
         List<TextSpan> regions = CMakeParsing.ParseForFunctionBodies(
             source.GetLines());
         foreach (TextSpan textSpan in regions)
         {
             req.Sink.AddHiddenRegion(textSpan);
         }
     }
     if (req.Sink.BraceMatching)
     {
         List<CMakeParsing.SpanPair> pairs = null;
         switch ((CMakeToken)req.TokenInfo.Token)
         {
         case CMakeToken.OpenParen:
         case CMakeToken.CloseParen:
             pairs = CMakeParsing.ParseForParens(source.GetLines());
             break;
         case CMakeToken.VariableStart:
         case CMakeToken.VariableStartEnv:
         case CMakeToken.VariableStartCache:
         case CMakeToken.VariableStartSetEnv:
         case CMakeToken.VariableEnd:
             pairs = CMakeParsing.ParseForVariableBraces(source.GetLines(),
                 req.Line);
             break;
         case CMakeToken.GeneratorStart:
         case CMakeToken.GeneratorEnd:
             pairs = CMakeParsing.ParseForGeneratorBraces(source.GetLines(),
                 req.Line);
             break;
         }
         if (pairs != null)
         {
             foreach (CMakeParsing.SpanPair pair in pairs)
             {
                 req.Sink.MatchPair(pair.First, pair.Second, 0);
             }
         }
     }
     if (req.Reason == ParseReason.MemberSelect ||
         req.Reason == ParseReason.MemberSelectAndHighlightBraces ||
         req.Reason == ParseReason.CompleteWord)
     {
         // Set an appropriate declarations object depending on the token that
         // triggered member selection.
         CMakeToken token = (CMakeToken)req.TokenInfo.Token;
         if (token == CMakeToken.String)
         {
             // If the token is a string and the user has began to reference a
             // variable inside the string, treat the string as if it was the
             // appropriate type of variable start token and display member
             // selection for variables.
             string line = source.GetLine(req.Line);
             string tokenText = line.ExtractToken(req.TokenInfo);
             if (tokenText.EndsWith("${"))
             {
                 token = CMakeToken.VariableStart;
             }
             else if (tokenText.EndsWith("$ENV{"))
             {
                 token = CMakeToken.VariableStartEnv;
             }
             else if (tokenText.EndsWith("$CACHE{"))
             {
                 token = CMakeToken.VariableStartCache;
             }
         }
         if (token == CMakeToken.VariableStart)
         {
             List<string> vars = CMakeParsing.ParseForVariables(
                 source.GetLines(), req.Line);
             CMakeVariableDeclarations decls = new CMakeVariableDeclarations(vars,
                 CMakeVariableType.Variable);
             decls.AddItems(source.GetIncludeCacheVariables(),
                 CMakeItemDeclarations.ItemType.Variable);
             string functionName = CMakeParsing.ParseForCurrentFunction(
                 source.GetLines(), req.Line);
             if (functionName != null)
             {
                 List<string> paramNames = CMakeParsing.ParseForParameterNames(
                     source.GetLines(), functionName);
                 paramNames.Add("ARGN");
                 decls.AddItems(paramNames,
                     CMakeItemDeclarations.ItemType.Variable);
             }
             scope.SetDeclarations(decls);
         }
         else if (token == CMakeToken.VariableStartEnv)
         {
             List<string> vars = CMakeParsing.ParseForEnvVariables(
                 source.GetLines());
             CMakeVariableDeclarations decls = new CMakeVariableDeclarations(vars,
                 CMakeVariableType.EnvVariable);
             decls.AddItems(source.GetIncludeCacheEnvVariables(),
                 CMakeItemDeclarations.ItemType.Variable);
             scope.SetDeclarations(decls);
         }
         else if (token == CMakeToken.VariableStartCache)
         {
             List<string> vars = CMakeParsing.ParseForCacheVariables(
                 source.GetLines());
             CMakeVariableDeclarations decls = new CMakeVariableDeclarations(vars,
                 CMakeVariableType.CacheVariable);
             decls.AddItems(source.GetIncludeCacheCacheVariables(),
                 CMakeItemDeclarations.ItemType.Variable);
             scope.SetDeclarations(decls);
         }
         else if (token == CMakeToken.Identifier)
         {
             CMakeParsing.TokenData tokenData;
             CMakeParsing.ParseForToken(source.GetLines(), req.Line,
                 req.TokenInfo.StartIndex, out tokenData);
             if (!tokenData.InParens)
             {
                 CMakeItemDeclarations decls = new CMakeItemDeclarations();
                 IEnumerable<string> commands = CMakeKeywords.GetAllCommands(
                     CMakePackage.Instance.CMakeOptionPage.ShowDeprecated);
                 if (!CMakePackage.Instance.CMakeOptionPage.CommandsLower)
                 {
                     commands = commands.Select(x => x.ToUpper());
                 }
                 decls.AddItems(commands, CMakeItemDeclarations.ItemType.Command);
                 decls.AddItems(
                     CMakeParsing.ParseForFunctionNames(source.GetLines(), false),
                     CMakeItemDeclarations.ItemType.Function);
                 decls.AddItems(
                     CMakeParsing.ParseForFunctionNames(source.GetLines(), true),
                     CMakeItemDeclarations.ItemType.Macro);
                 decls.AddItems(source.GetIncludeCacheFunctions(),
                     CMakeItemDeclarations.ItemType.Function);
                 decls.AddItems(source.GetIncludeCacheMacros(),
                     CMakeItemDeclarations.ItemType.Macro);
                 scope.SetDeclarations(decls);
             }
             else
             {
                 Declarations decls = CMakeDeclarationsFactory.CreateDeclarations(
                     tokenData.Command, req, source,
                     tokenData.ParameterIndex > 0 ? tokenData.PriorParameters : null);
                 scope.SetDeclarations(decls);
             }
         }
         else if (token == CMakeToken.OpenParen)
         {
             CMakeCommandId id = CMakeParsing.ParseForTriggerCommandId(
                 source.GetLines(), req.Line, req.TokenInfo.StartIndex);
             Declarations decls = CMakeDeclarationsFactory.CreateDeclarations(
                 id, req, source);
             scope.SetDeclarations(decls);
         }
         else if (token == CMakeToken.WhiteSpace)
         {
             CMakeParsing.TokenData tokenData;
             CMakeParsing.ParseForToken(source.GetLines(), req.Line,
                 req.TokenInfo.StartIndex, out tokenData);
             Declarations decls = CMakeDeclarationsFactory.CreateDeclarations(
                 tokenData.Command, req, source,
                 tokenData.ParameterIndex > 0 ? tokenData.PriorParameters : null);
             scope.SetDeclarations(decls);
         }
         else if (token == CMakeToken.GeneratorStart)
         {
             scope.SetDeclarations(new CMakeGeneratorDeclarations());
         }
     }
     else if (req.Reason == ParseReason.MethodTip)
     {
         CMakeParsing.ParameterInfoResult result =
             CMakeParsing.ParseForParameterInfo(source.GetLines(), req.Line,
             req.TokenInfo.EndIndex);
         if (result.CommandName != null && result.CommandSpan.HasValue)
         {
             if (result.SubcommandName == null)
             {
                 req.Sink.StartName(result.CommandSpan.Value, result.CommandName);
             }
             else
             {
                 req.Sink.StartName(result.CommandSpan.Value,
                     result.CommandSpan + "(" + result.SubcommandName);
             }
             if (result.BeginSpan.HasValue)
             {
                 req.Sink.StartParameters(result.BeginSpan.Value);
             }
             foreach (TextSpan span in result.SeparatorSpans)
             {
                 req.Sink.NextParameter(span);
             }
             if (result.EndSpan.HasValue)
             {
                 req.Sink.EndParameters(result.EndSpan.Value);
             }
             CMakeCommandId id = CMakeKeywords.GetCommandId(result.CommandName);
             if (id == CMakeCommandId.Unspecified)
             {
                 // If it's a user-defined function or macro, parse to try to find
                 // its parameters.
                 List<string> parameters = CMakeParsing.ParseForParameterNames(
                     source.GetLines(), result.CommandName);
                 if (parameters == null)
                 {
                     parameters = source.GetParametersFromIncludeCache(
                         result.CommandName);
                 }
                 if (parameters != null)
                 {
                     scope.SetMethods(new CMakeUserMethods(result.CommandName,
                         parameters));
                 }
             }
             else
             {
                 scope.SetMethods(CMakeMethods.GetCommandParameters(id,
                     result.SubcommandName));
             }
         }
     }
     else if (req.Reason == ParseReason.Goto)
     {
         scope.SetLines(source.GetLines());
         scope.SetFileName(req.FileName);
     }
     else if (req.Reason == ParseReason.QuickInfo)
     {
         scope.SetLines(source.GetLines());
     }
     else if (req.Reason == ParseReason.Check)
     {
         foreach (ParseForErrorMethod method in _parseForErrorMethods)
         {
             List<CMakeErrorInfo> info = method(source.GetLines());
             foreach (CMakeErrorInfo item in info)
             {
                 CMakeError err = item.ErrorCode;
                 if (_errorStrings.ContainsKey(err) &&
                     (!_enabledMethods.ContainsKey(err) || _enabledMethods[err]()))
                 {
                     req.Sink.AddError(req.FileName, _errorStrings[err], item.Span,
                         item.Warning ? Severity.Warning : Severity.Error);
                 }
             }
         }
         if (CMakePackage.Instance.CMakeOptionPage.ParseIncludedFiles)
         {
             source.BuildIncludeCache(source.GetLines());
             source.UpdateIncludeCache();
             source.PruneIncludeCache();
         }
         else
         {
             source.ClearIncludeCache();
         }
     }
     return scope;
 }