예제 #1
0
 public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
 {
     foreach (var decl in node.Declaration.Variables)
     {
         Visit(decl.Initializer?.Value);
     }
 }
        static bool IsDeclarationConstFriendly(LocalDeclarationStatementSyntax declaration, SemanticModel semanticModel)
        {
            // all variables could be const?
            foreach (var variable in declaration.Declaration.Variables)
            {
                if (variable.Initializer == null) return false;
                if (variable.Initializer.Value is InterpolatedStringExpressionSyntax) return false;

                // is constant
                var constantValue = semanticModel.GetConstantValue(variable.Initializer.Value);
                var valueIsConstant = constantValue.HasValue;
                if (!valueIsConstant) return false;

                // if reference type, value is null?
                var variableTypeName = declaration.Declaration.Type;
                var variableType = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;
                if (variableType.IsReferenceType && variableType.SpecialType != SpecialType.System_String && constantValue.Value != null) return false;

                // nullable?
                if (variableType.OriginalDefinition?.SpecialType == SpecialType.System_Nullable_T) return false;

                // value can be converted to variable type?
                var conversion = semanticModel.ClassifyConversion(variable.Initializer.Value, variableType);
                if (!conversion.Exists || conversion.IsUserDefined) return false;
            }
            return true;
        }
예제 #3
0
        public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            if (node.Declaration.Variables.Count > 1)
                return node;
            if (node.Declaration.Variables[0].Initializer == null)
                return node;

            VariableDeclaratorSyntax declarator = node.Declaration.Variables.First();
            TypeSyntax variableTypeName = node.Declaration.Type;

            ITypeSymbol variableType = (ITypeSymbol)SemanticModel.GetSymbolInfo(variableTypeName).Symbol;

            TypeInfo initializerInfo = SemanticModel.GetTypeInfo(declarator.Initializer.Value);

            if (variableType == initializerInfo.Type)
            {
                TypeSyntax varTypeName = SyntaxFactory.IdentifierName("var")
                                                .WithLeadingTrivia(variableTypeName.GetLeadingTrivia())
                                                .WithTrailingTrivia(variableTypeName.GetTrailingTrivia());

                return node.ReplaceNode(variableTypeName, varTypeName);
            }
            else
            {
                return node;
            }
        }
예제 #4
0
            public override SyntaxNode VisitLocalDeclarationStatement(Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax node)
            {
                if (_methodName == null)
                {
                    return(node);
                }
                if (node.Declaration.Variables.Count > 1)
                {
                    return(node);
                }
                var identifier = node.Declaration.Variables.Single().Identifier.ValueText;

                if (!s_validIdentifierNames.Contains(identifier))
                {
                    return(node);
                }

                Console.WriteLine($"Fixing {_methodName}");
                var oldInitializer = node.Declaration.Variables.Single().Initializer.Value;
                var newInitializer = Microsoft.CodeAnalysis.CSharp.SyntaxFactory.LiteralExpression(
                    Microsoft.CodeAnalysis.CSharp.SyntaxKind.StringLiteralExpression,
                    Microsoft.CodeAnalysis.CSharp.SyntaxFactory.Literal(
                        $@"@""
{replaceDetails[_methodName].Replace("\"", "\"\"")}
""",
                        Environment.NewLine));

                replaceDetails.Remove(_methodName);
                _methodName = null;
                return(node.ReplaceNode(oldInitializer, newInitializer));
            }
		private Document IntroduceLocalDeclarationIntoLambda(
			SemanticDocument document,
			ExpressionSyntax expression,
			IdentifierNameSyntax newLocalName,
			LocalDeclarationStatementSyntax declarationStatement,
			SyntaxNode oldLambda,
			bool allOccurrences,
			CancellationToken cancellationToken)
		{
			var oldBody = oldLambda is ParenthesizedLambdaExpressionSyntax
				? (ExpressionSyntax)((ParenthesizedLambdaExpressionSyntax)oldLambda).Body
			                                                                        : (ExpressionSyntax)((SimpleLambdaExpressionSyntax)oldLambda).Body;

			var rewrittenBody = Rewrite(
				document, expression, newLocalName, document, oldBody, allOccurrences, cancellationToken);

			var delegateType = document.SemanticModel.GetTypeInfo(oldLambda, cancellationToken).ConvertedType as INamedTypeSymbol;

			var newBody = delegateType != null && delegateType.DelegateInvokeMethod != null && delegateType.DelegateInvokeMethod.ReturnsVoid
			                                                  ? SyntaxFactory.Block(declarationStatement)
			                                                  : SyntaxFactory.Block(declarationStatement, SyntaxFactory.ReturnStatement(rewrittenBody));

			newBody = newBody.WithAdditionalAnnotations(Formatter.Annotation);

			var newLambda = oldLambda is ParenthesizedLambdaExpressionSyntax
				? ((ParenthesizedLambdaExpressionSyntax)oldLambda).WithBody(newBody)
			                                                      : (SyntaxNode)((SimpleLambdaExpressionSyntax)oldLambda).WithBody(newBody);

			var newRoot = document.Root.ReplaceNode(oldLambda, newLambda);
			return document.Document.WithSyntaxRoot(newRoot);
		}
        private async static Task<Document> RemoveVariableAsync(Document document, LocalDeclarationStatementSyntax variableUnused, CancellationToken cancellationToken)
        {
            var root = await document.GetSyntaxRootAsync(cancellationToken);

            var newRoot = root.RemoveNode(variableUnused, SyntaxRemoveOptions.KeepNoTrivia);

            return document.WithSyntaxRoot(newRoot);
        }
        private bool VarIsAppropriate(LocalDeclarationStatementSyntax decl)
        {
            foreach (var assignment in decl.Declaration.Variables)
            {
            }

            return false;
        }
 static bool AreVariablesOnlyWrittenInsideDeclaration(LocalDeclarationStatementSyntax declaration, SemanticModel semanticModel)
 {
     var dfa = semanticModel.AnalyzeDataFlow(declaration);
     var symbols = from variable in declaration.Declaration.Variables
                   select semanticModel.GetDeclaredSymbol(variable);
     var result = !symbols.Any(s => dfa.WrittenOutside.Contains(s));
     return result;
 }
예제 #9
0
 public static glsl.LocalDeclarationStatementSyntax Translate(this cs.LocalDeclarationStatementSyntax node)
 {
     return(new glsl.LocalDeclarationStatementSyntax()
     {
         Declaration = node.Declaration.Translate(),
         SemicolonToken = node.SemicolonToken,
     });
 }
 public Rewriter(
     BlockSyntax oldInnermostBlock,
     BlockSyntax newInnermostBlock,
     BlockSyntax oldOutermostBlock,
     LocalDeclarationStatementSyntax declarationStatement)
 {
     _oldInnermostBlock = oldInnermostBlock;
     _newInnermostBlock = newInnermostBlock;
     _oldOutermostBlock = oldOutermostBlock;
     _declarationStatement = declarationStatement;
 }
        static bool TryValidateLocalVariableType(LocalDeclarationStatementSyntax localDeclarationStatementSyntax, VariableDeclarationSyntax variableDeclarationSyntax)
        {
            //Either we don't have a local variable or we're using constant value
            if (localDeclarationStatementSyntax == null ||
                localDeclarationStatementSyntax.IsConst ||
                localDeclarationStatementSyntax.ChildNodes().OfType<VariableDeclarationSyntax>().Count() != 1)
                return false;

            //We don't want to raise a diagnostic if the local variable is already a var
            return !variableDeclarationSyntax.Type.IsVar;
        }
            internal static async Task<State> GenerateAsync(
                SemanticDocument document,
                LocalDeclarationStatementSyntax statement,
                CancellationToken cancellationToken)
            {
                var state = new State();
                if (!await state.TryInitializeAsync(document, statement, cancellationToken).ConfigureAwait(false))
                {
                    return null;
                }

                return state;
            }
        static bool IsArrayTypeSomeObviousTypeCase(SyntaxNodeAnalysisContext nodeContext, ExpressionSyntax initializerExpression, ITypeSymbol variableType, LocalDeclarationStatementSyntax localVariable)
        {
            var arrayCreationExpressionSyntax = initializerExpression as ArrayCreationExpressionSyntax;
            if (arrayCreationExpressionSyntax != null)
            {
                if (arrayCreationExpressionSyntax.Type.IsMissing)
                    return false;

                var arrayType = nodeContext.SemanticModel.GetTypeInfo(arrayCreationExpressionSyntax).Type;
                return arrayType != null && arrayCreationExpressionSyntax.Initializer != null && variableType.Equals(arrayType);
            }

            return false;
        }
예제 #14
0
        public override SyntaxList <StatementSyntax> VisitLocalDeclarationStatement(CSS.LocalDeclarationStatementSyntax node)
        {
            var modifiers = CommonConversions.ConvertModifiers(node.Modifiers, TokenContext.Local);

            if (modifiers.Count == 0)
            {
                modifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.DimKeyword));
            }
            return(SyntaxFactory.SingletonList <StatementSyntax>(
                       SyntaxFactory.LocalDeclarationStatement(
                           modifiers, _commonConversions.RemodelVariableDeclaration(node.Declaration)
                           )
                       ));
        }
        public static string GetVariableName(this Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax localNodeDeclaration)
        {
            if (localNodeDeclaration == null)
            {
                return(null);
            }

            var identifierDeclaration = localNodeDeclaration?.Declaration?.Variables.FirstOrDefault();

            if (identifierDeclaration.Identifier != null)
            {
                return(identifierDeclaration.Identifier.ValueText);
            }
            return(null);
        }
        static bool DidVariableDeclarationTypeCorrespondToObviousCase(SyntaxNodeAnalysisContext nodeContext, LocalDeclarationStatementSyntax localVariable)
        {
            var singleVariable = localVariable.Declaration.Variables.First();
            var initializer = singleVariable.Initializer;
            if (initializer == null)
                return false;
            var initializerExpression = initializer.Value;

            var variableTypeName = localVariable.Declaration.Type;
            var semanticModel = nodeContext.SemanticModel;
            var variableType = semanticModel.GetSymbolInfo(variableTypeName, nodeContext.CancellationToken).Symbol as ITypeSymbol;
            return IsArrayTypeSomeObviousTypeCase(nodeContext, initializerExpression, variableType, localVariable) ||
                IsObjectCreationSomeObviousTypeCase(nodeContext, initializerExpression, variableType) ||
                IsCastingSomeObviousTypeCase(nodeContext, initializerExpression, variableType) /*||
				IsPropertyAccessSomeObviousTypeCase(nodeContext, initializerExpression, variableType)*/;
        }
		public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
		{
			if (this.InsideAutoIncludeMethodBlock)
			{
				var allchildren = node.DescendantNodesAndTokens(descendIntoTrivia: true);
				var line = node.SyntaxTree.GetLineSpan(node.Span).StartLinePosition.Line;
				if (allchildren.Any(a => a.Kind() == SyntaxKind.MultiLineDocumentationCommentTrivia))
				{
					var walker = new CodeWithDocumentationWalker(ClassDepth, line);
					walker.Visit(node.WithAdditionalAnnotations());
					this.Blocks.AddRange(walker.Blocks);
					return;
				}
				this.Blocks.Add(new CodeBlock(node.WithoutLeadingTrivia().ToFullString(), line));
			}
			base.VisitLocalDeclarationStatement(node);
		}
예제 #18
0
        private bool TryGenerateLocal(LocalDeclarationStatementSyntax localDeclarationStatement)
        {
            /*
              - <ElementType name="Local" content="eltOnly">
                    <attribute type="id" /> 
                    <attribute type="static" /> 
                    <attribute type="instance" /> 
                    <attribute type="implicit" /> 
                    <attribute type="constant" /> 
                - <group order="one">
                        <element type="Type" /> 
                        <element type="ArrayType" /> 
                    </group>
                - <group minOccurs="1" maxOccurs="*" order="seq">
                        <element type="LocalName" /> 
                        <element type="Expression" minOccurs="0" maxOccurs="1" /> 
                    </group>
                </ElementType>
            */

            using (LocalTag(GetLineNumber(localDeclarationStatement)))
            {
                // Spew the type first
                if (!TryGenerateType(localDeclarationStatement.Declaration.Type))
                {
                    return false;
                }

                // Now spew the list of variables
                foreach (var variable in localDeclarationStatement.Declaration.Variables)
                {
                    GenerateName(variable.Identifier.ToString());

                    if (variable.Initializer != null)
                    {
                        if (!TryGenerateExpression(variable.Initializer.Value))
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }
        public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            var semanticModel = compilation.GetSemanticModel(node.SyntaxTree);

            // Convert the variable declaration to an assignment expression statement
            foreach (var variable in node.Declaration.Variables)
            {
                if (variable.Initializer != null)
                {
                    var assignment = SyntaxFactory.IdentifierName(variable.Identifier.ToString()).Assign(StateMachineThisFixer.Fix(variable.Initializer.Value));
                    currentState.Add(Cs.Express(assignment));
                }

                // Hoist the variable into a field
                var symbol = (ILocalSymbol)ModelExtensions.GetDeclaredSymbol(semanticModel, variable);
                node = (LocalDeclarationStatementSyntax)HoistVariable(node, variable.Identifier, symbol.Type.ToTypeSyntax());
            }
        }
        public static string GetRightAssignmentDataType(this Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax localNodeDeclaration)
        {
            if (localNodeDeclaration == null)
            {
                return(null);
            }

            var identifierDeclaration = localNodeDeclaration?.Declaration?.Variables.FirstOrDefault() as VariableDeclaratorSyntax;

            switch (identifierDeclaration?.Initializer)
            {
            case EqualsValueClauseSyntax equalValueClause:
                return(TryGetEqualsValueClause(equalValueClause));

            default:
                return(null);
            }
        }
예제 #21
0
        public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            var symbolInfo = model.GetSymbolInfo(node.Declaration.Type);
            var typeSymbol = symbolInfo.Symbol;
            var type = typeSymbol.ToDisplayString(
              SymbolDisplayFormat.MinimallyQualifiedFormat);

            var declaration = SyntaxFactory
                .LocalDeclarationStatement(
                    SyntaxFactory
                        .VariableDeclaration(SyntaxFactory.IdentifierName(
                          SyntaxFactory.Identifier(type)))
                            .WithVariables(node.Declaration.Variables)
                            .NormalizeWhitespace()
                    )
                    .WithTriviaFrom(node);
            return declaration;
        }
예제 #22
0
        private async Task<Document> MakeConstAsync(Document document, LocalDeclarationStatementSyntax localDeclaration, CancellationToken cancellationToken)
        {
            var firstToken = localDeclaration.GetFirstToken();
            var leadingTrivia = firstToken.LeadingTrivia;
            var trimmedLocal = localDeclaration.ReplaceToken(firstToken, firstToken.WithLeadingTrivia(SyntaxTriviaList.Empty));

            var constToken = SyntaxFactory.Token(leadingTrivia, SyntaxKind.ConstKeyword, SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker));

            var newModifiers = trimmedLocal.Modifiers.Insert(0, constToken);

            var variableDeclaration = localDeclaration.Declaration;
            var variableTypeName = variableDeclaration.Type;
            if (variableTypeName.IsVar)
            {
                var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

                var aliasInfo = semanticModel.GetAliasInfo(variableTypeName);
                if (aliasInfo == null)
                {
                    var type = semanticModel.GetTypeInfo(variableTypeName).ConvertedType;

                    if (type.Name != "var")
                    {
                        var typeName = SyntaxFactory.ParseTypeName(type.ToDisplayString())
                            .WithLeadingTrivia(variableTypeName.GetLeadingTrivia())
                            .WithTrailingTrivia(variableTypeName.GetTrailingTrivia());

                        var simplifiedTypeName = typeName.WithAdditionalAnnotations(Simplifier.Annotation);

                        variableDeclaration = variableDeclaration.WithType(simplifiedTypeName);
                    }
                }
            }

            var newLocal = trimmedLocal.WithModifiers(newModifiers)
                                       .WithDeclaration(variableDeclaration);

            var formattedLocal = newLocal.WithAdditionalAnnotations(Formatter.Annotation);

            var root = await document.GetSyntaxRootAsync(cancellationToken);
            var newRoot = root.ReplaceNode(localDeclaration, formattedLocal);

            return document.WithSyntaxRoot(newRoot);
        }
        /// <summary>
        /// Get variable type from 'LocalDeclarationStatementSyntax'
        /// </summary>
        /// <param name="localNodeDeclaration"></param>
        public static string GetVariableType(this Microsoft.CodeAnalysis.CSharp.Syntax.LocalDeclarationStatementSyntax localNodeDeclaration)
        {
            if (localNodeDeclaration == null)
            {
                return(null);
            }

            var identifierDeclaration = localNodeDeclaration?.Declaration;

            switch (localNodeDeclaration?.Declaration?.Type)
            {
            case IdentifierNameSyntax declaredType:
                return(declaredType.Identifier.ValueText);

            case PredefinedTypeSyntax predefinedType:
                return(predefinedType?.Keyword.ValueText);
            }
            return(null);
        }
        public static void Go(OutputWriter writer, LocalDeclarationStatementSyntax declaration)
        {
            foreach (var variable in declaration.Declaration.Variables)
            {


                writer.WriteIndent();
               
                {
                    try
                    {
                        var str = TypeProcessor.ConvertType(declaration.Declaration.Type);
                        //This fails sometimes
                        // if (str == "NObject") // Dlangs casting is slow 
                        // Looks harmless but is actually a performance optimization ... makes CastTest improve by a whole lot
                        //   writer.Write("auto ");//Kills BoxingTest unfortunately as boxed types are also used to make unbound generics work :(
                        //else
                        writer.Write(str);
                    }
                    catch (Exception ex)
                    {
                        writer.Write("auto");   
                    }
                   

                    writer.Write(" ");



                    writer.Write(WriteIdentifierName.TransformIdentifier(variable.Identifier.Text));
                    writer.Write(" = ");

                     WriteInitializer(writer, declaration, variable);
                }

                writer.Write(";\r\n");
            }
        }
            private async Task<bool> TryInitializeAsync(
                SemanticDocument document,
                LocalDeclarationStatementSyntax node,
                CancellationToken cancellationToken)
            {
                if (node == null)
                {
                    return false;
                }

                this.DeclarationStatement = node;
                if (!(this.DeclarationStatement.IsParentKind(SyntaxKind.Block) &&
                      this.DeclarationStatement.Declaration.Variables.Count == 1))
                {
                    return false;
                }

                this.VariableDeclaration = this.DeclarationStatement.Declaration;
                this.VariableDeclarator = this.VariableDeclaration.Variables[0];
                this.OutermostBlock = (BlockSyntax)this.DeclarationStatement.Parent;
                this.LocalSymbol = (ILocalSymbol)document.SemanticModel.GetDeclaredSymbol(this.VariableDeclarator, cancellationToken);
                if (this.LocalSymbol == null)
                {
                    // This can happen in broken code, for example: "{ object x; object }"
                    return false;
                }

                var findReferencesResult = await SymbolFinder.FindReferencesAsync(this.LocalSymbol, document.Project.Solution, cancellationToken).ConfigureAwait(false);
                var findReferencesList = findReferencesResult.ToList();
                if (findReferencesList.Count != 1)
                {
                    return false;
                }

                var references = findReferencesList[0].Locations.ToList();
                if (references.Count == 0)
                {
                    return false;
                }

                var syntaxTree = document.SyntaxTree;
                var referencingStatements =
                    (from r in references
                     let token = document.Root.FindToken(r.Location.SourceSpan.Start)
                     let statement = token.GetAncestor<StatementSyntax>()
                     where statement != null
                     select statement).ToList();

                if (referencingStatements.Count == 0)
                {
                    return false;
                }

                this.InnermostBlock = referencingStatements.FindInnermostCommonBlock();

                var allAffectedStatements = new HashSet<StatementSyntax>(referencingStatements.SelectMany(expr => expr.GetAncestorsOrThis<StatementSyntax>()));
                this.FirstStatementAffectedInInnermostBlock = this.InnermostBlock.Statements.FirstOrDefault(allAffectedStatements.Contains);

                if (this.FirstStatementAffectedInInnermostBlock == null)
                {
                    return false;
                }

                if (this.FirstStatementAffectedInInnermostBlock == this.DeclarationStatement)
                {
                    return false;
                }

                var originalIndexInBlock = this.InnermostBlock.Statements.IndexOf(this.DeclarationStatement);
                var firstStatementIndexAffectedInBlock = this.InnermostBlock.Statements.IndexOf(this.FirstStatementAffectedInInnermostBlock);
                if (originalIndexInBlock >= 0 &&
                    originalIndexInBlock < firstStatementIndexAffectedInBlock)
                {
                    // Don't want to move a decl past other decls in order to move it to the first
                    // affected statement.  If we do we can end up in the following situation: 
#if false
                    int x = 0;
                    int y = 0;
                    Console.WriteLine(x + y);
#endif
                    // Each of these declarations will want to 'move' down to the WriteLine
                    // statement and we don't want to keep offering the refactoring.  Note: this
                    // solution is overly aggressive.  Technically if 'y' weren't referenced in
                    // Console.Writeline, then it might be a good idea to move the 'x'.  But this
                    // gives good enough behavior most of the time.
                    if (InDeclarationStatementGroup(originalIndexInBlock, firstStatementIndexAffectedInBlock))
                    {
                        return false;
                    }
                }

                var previousNodeOrToken = firstStatementIndexAffectedInBlock == 0
                    ? this.InnermostBlock.OpenBraceToken
                    : (SyntaxNodeOrToken)this.InnermostBlock.Statements[firstStatementIndexAffectedInBlock - 1];
                var affectedSpan = TextSpan.FromBounds(previousNodeOrToken.SpanStart, FirstStatementAffectedInInnermostBlock.Span.End);
                if (syntaxTree.OverlapsHiddenPosition(affectedSpan, cancellationToken))
                {
                    return false;
                }

                return true;
            }
            // Extracts the name of the variable from a local declaration statement, returns a SyntaxToken of "" if analysis failed
            private SyntaxToken GetIdentifierTokenFromLocalDecl(LocalDeclarationStatementSyntax statement)
            {
                var emptyResult = SyntaxFactory.Identifier("");

                if (statement == null)
                {
                    return emptyResult;
                }

                var variableDeclaration = statement.Declaration as VariableDeclarationSyntax;
                if (variableDeclaration == null)
                {
                    return emptyResult;
                }

                SeparatedSyntaxList<VariableDeclaratorSyntax> variables = variableDeclaration.Variables;
                if (variables == null || variables.Count != 1)
                {
                    return emptyResult;
                }

                var variableDeclarator = variables[0] as VariableDeclaratorSyntax;
                if (variableDeclarator == null)
                {
                    return emptyResult;
                }

                SyntaxToken identifier = variableDeclarator.Identifier;
                if (identifier == null)
                {
                    return emptyResult;
                }

                return identifier;
            }
            // Extracts the equals value clause from a local declaration statement, returns null if failed
            private EqualsValueClauseSyntax GetEqualsValueClauseFromLocalDecl(LocalDeclarationStatementSyntax statement)
            {
                EqualsValueClauseSyntax emptyResult = null;

                if (statement == null)
                {
                    return emptyResult;
                }

                var variableDeclaration = statement.Declaration as VariableDeclarationSyntax;
                if (variableDeclaration == null)
                {
                    return emptyResult;
                }

                SeparatedSyntaxList<VariableDeclaratorSyntax> variables = variableDeclaration.Variables;
                if (variables == null || variables.Count != 1)
                {
                    return emptyResult;
                }

                var variableDeclarator = variables[0] as VariableDeclaratorSyntax;
                if (variableDeclarator == null)
                {
                    return emptyResult;
                }

                SyntaxToken identifier = variableDeclarator.Identifier;
                if (identifier == null)
                {
                    return emptyResult;
                }

                var equalsValueClause = variableDeclarator.Initializer as EqualsValueClauseSyntax;
                if (equalsValueClause == null)
                {
                    return emptyResult;
                }

                return equalsValueClause;
            }
        private bool IsAccessed(
            SemanticModel semanticModel,
            ISymbol outSymbol, 
            BlockSyntax enclosingBlockOfLocalStatement,
            LocalDeclarationStatementSyntax localStatement, 
            ArgumentSyntax argumentNode,
            CancellationToken cancellationToken)
        {
            var localStatementStart = localStatement.Span.Start;
            var argumentNodeStart = argumentNode.Span.Start;
            var variableName = outSymbol.Name;

            // Walk the block that the local is declared in looking for accesses.
            // We can ignore anything prior to the actual local declaration point,
            // and we only need to check up until we reach the out-argument.
            foreach (var descendentNode in enclosingBlockOfLocalStatement.DescendantNodes())
            {
                var descendentStart = descendentNode.Span.Start;
                if (descendentStart <= localStatementStart)
                {
                    // This node is before the local declaration.  Can ignore it entirely as it could
                    // not be an access to the local.
                    continue;
                }

                if (descendentStart >= argumentNodeStart)
                {
                    // We reached the out-var.  We can stop searching entirely.
                    break;
                }

                if (descendentNode.IsKind(SyntaxKind.IdentifierName))
                {
                    // See if this looks like an accessor to the local variable syntactically.
                    var identifierName = (IdentifierNameSyntax)descendentNode;
                    if (identifierName.Identifier.ValueText == variableName)
                    {
                        // Confirm that it is a access of the local.
                        var symbol = semanticModel.GetSymbolInfo(identifierName, cancellationToken).Symbol;
                        if (outSymbol.Equals(symbol))
                        {
                            // We definitely accessed the local before the out-argument.  We 
                            // can't inline this local.
                            return true;
                        }
                    }
                }
            }

            // No accesses detected
            return false;
        }
예제 #29
0
        private BoundStatement BindDeclarationStatement(LocalDeclarationStatementSyntax node, DiagnosticBag diagnostics)
        {
            var typeSyntax = node.Declaration.Type;
            bool isConst = node.IsConst;

            bool isVar;
            AliasSymbol alias;
            TypeSymbol declType = BindVariableType(node, diagnostics, typeSyntax, ref isConst, isVar: out isVar, alias: out alias);

            // UNDONE: "possible expression" feature for IDE

            LocalDeclarationKind kind = LocalDeclarationKind.RegularVariable;
            if (isConst)
            {
                kind = LocalDeclarationKind.Constant;
            }

            var variableList = node.Declaration.Variables;
            int variableCount = variableList.Count;

            if (variableCount == 1)
            {
                return BindVariableDeclaration(kind, isVar, variableList[0], typeSyntax, declType, alias, diagnostics, node);
            }
            else
            {
                BoundLocalDeclaration[] boundDeclarations = new BoundLocalDeclaration[variableCount];

                int i = 0;
                foreach (var variableDeclaratorSyntax in variableList)
                {
                    boundDeclarations[i++] = BindVariableDeclaration(kind, isVar, variableDeclaratorSyntax, typeSyntax, declType, alias, diagnostics);
                }

                return new BoundMultipleLocalDeclarations(node, boundDeclarations.AsImmutableOrNull());
            }
        }
            public override SyntaxList <VB.Syntax.StatementSyntax> VisitLocalDeclarationStatement(CS.Syntax.LocalDeclarationStatementSyntax node)
            {
                SyntaxTriviaList leadingTrivia = TriviaList(node.GetFirstToken(includeSkipped: true).LeadingTrivia.SelectMany(nodeVisitor.VisitTrivia));

                SyntaxToken token = node.Modifiers.Any(t => t.IsKind(CS.SyntaxKind.ConstKeyword))
                    ? VB.SyntaxFactory.Token(leadingTrivia, VB.SyntaxKind.ConstKeyword)
                    : VB.SyntaxFactory.Token(leadingTrivia, VB.SyntaxKind.DimKeyword);

                return(List <VB.Syntax.StatementSyntax>(
                           VB.SyntaxFactory.FieldDeclaration(
                               new SyntaxList <VB.Syntax.AttributeListSyntax>(),
                               SyntaxTokenList.Create(token),
                               SeparatedCommaList(node.Declaration.Variables.Select(nodeVisitor.Visit <VB.Syntax.VariableDeclaratorSyntax>)))));
            }
        private Document RewriteExpressionBodiedMemberAndIntroduceLocalDeclaration(
            SemanticDocument document,
            ArrowExpressionClauseSyntax arrowExpression,
            ExpressionSyntax expression,
            NameSyntax newLocalName,
            LocalDeclarationStatementSyntax declarationStatement,
            bool allOccurrences,
            CancellationToken cancellationToken)
        {
            var oldBody = arrowExpression;
            var oldParentingNode = oldBody.Parent;
            var leadingTrivia = oldBody.GetLeadingTrivia()
                                       .AddRange(oldBody.ArrowToken.TrailingTrivia);

            var newStatement = Rewrite(document, expression, newLocalName, document, oldBody.Expression, allOccurrences, cancellationToken);
            var newBody = SyntaxFactory.Block(declarationStatement, SyntaxFactory.ReturnStatement(newStatement))
                                       .WithLeadingTrivia(leadingTrivia)
                                       .WithTrailingTrivia(oldBody.GetTrailingTrivia())
                                       .WithAdditionalAnnotations(Formatter.Annotation);

            SyntaxNode newParentingNode = null;
            if (oldParentingNode is BasePropertyDeclarationSyntax)
            {
                var getAccessor = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, newBody);
                var accessorList = SyntaxFactory.AccessorList(SyntaxFactory.List(new[] { getAccessor }));

                newParentingNode = ((BasePropertyDeclarationSyntax)oldParentingNode).RemoveNode(oldBody, SyntaxRemoveOptions.KeepNoTrivia);

                if (newParentingNode.IsKind(SyntaxKind.PropertyDeclaration))
                {
                    var propertyDeclaration = ((PropertyDeclarationSyntax)newParentingNode);
                    newParentingNode = propertyDeclaration
                        .WithAccessorList(accessorList)
                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                        .WithTrailingTrivia(propertyDeclaration.SemicolonToken.TrailingTrivia);
                }
                else if (newParentingNode.IsKind(SyntaxKind.IndexerDeclaration))
                {
                    var indexerDeclaration = ((IndexerDeclarationSyntax)newParentingNode);
                    newParentingNode = indexerDeclaration
                        .WithAccessorList(accessorList)
                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                        .WithTrailingTrivia(indexerDeclaration.SemicolonToken.TrailingTrivia);
                }
            }
            else if (oldParentingNode is BaseMethodDeclarationSyntax)
            {
                newParentingNode = ((BaseMethodDeclarationSyntax)oldParentingNode)
                    .RemoveNode(oldBody, SyntaxRemoveOptions.KeepNoTrivia)
                    .WithBody(newBody);

                if (newParentingNode.IsKind(SyntaxKind.MethodDeclaration))
                {
                    var methodDeclaration = ((MethodDeclarationSyntax)newParentingNode);
                    newParentingNode = methodDeclaration
                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                        .WithTrailingTrivia(methodDeclaration.SemicolonToken.TrailingTrivia);
                }
                else if (newParentingNode.IsKind(SyntaxKind.OperatorDeclaration))
                {
                    var operatorDeclaration = ((OperatorDeclarationSyntax)newParentingNode);
                    newParentingNode = operatorDeclaration
                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                        .WithTrailingTrivia(operatorDeclaration.SemicolonToken.TrailingTrivia);
                }
                else if (newParentingNode.IsKind(SyntaxKind.ConversionOperatorDeclaration))
                {
                    var conversionOperatorDeclaration = ((ConversionOperatorDeclarationSyntax)newParentingNode);
                    newParentingNode = conversionOperatorDeclaration
                        .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None))
                        .WithTrailingTrivia(conversionOperatorDeclaration.SemicolonToken.TrailingTrivia);
                }
            }

            var newRoot = document.Root.ReplaceNode(oldParentingNode, newParentingNode);
            return document.Document.WithSyntaxRoot(newRoot);
        }
예제 #32
0
        public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            if (node.Declaration.Variables.Count == 1)
            {
                var variable = node
                    .Declaration
                    .Variables[0];

                if (variable.Initializer != null)
                {
                    var call = variable.Initializer.Value as InvocationExpressionSyntax;
                    if (call != null)
                    {
                        SyntacticalExtension<SyntaxNode> extension = codeExtension(call);
                        if (extension != null)
                        {

                            if (extension.Kind != ExtensionKind.Code)
                            {
                                //td: error, incorrect extension (i.e. a code extension being used inside a type)
                                return node;
                            }

                            _lookahead = CheckCodeExtension(node, extension);
                            return null;
                        }
                    }
                }
            }

            return base.VisitLocalDeclarationStatement(node);
        }
        private async Task<Document> IntroduceLocalDeclarationIntoBlockAsync(
            SemanticDocument document,
            BlockSyntax block,
            ExpressionSyntax expression,
            NameSyntax newLocalName,
            LocalDeclarationStatementSyntax declarationStatement,
            bool allOccurrences,
            CancellationToken cancellationToken)
        {
            declarationStatement = declarationStatement.WithAdditionalAnnotations(Formatter.Annotation);

            var oldOutermostBlock = block;
            var matches = FindMatches(document, expression, document, oldOutermostBlock, allOccurrences, cancellationToken);
            Debug.Assert(matches.Contains(expression));

            var complexified = await ComplexifyParentingStatements(document, matches, cancellationToken).ConfigureAwait(false);
            document = complexified.Item1;
            matches = complexified.Item2;

            // Our original expression should have been one of the matches, which were tracked as part
            // of complexification, so we can retrieve the latest version of the expression here.
            expression = document.Root.GetCurrentNodes(expression).First();

            var innermostStatements = new HashSet<StatementSyntax>(
                matches.Select(expr => expr.GetAncestorOrThis<StatementSyntax>()));

            if (innermostStatements.Count == 1)
            {
                // If there was only one match, or all the matches came from the same
                // statement, then we want to place the declaration right above that
                // statement. Note: we special case this because the statement we are going
                // to go above might not be in a block and we may have to generate it
                return IntroduceLocalForSingleOccurrenceIntoBlock(
                    document, expression, newLocalName, declarationStatement, allOccurrences, cancellationToken);
            }

            var oldInnerMostCommonBlock = matches.FindInnermostCommonBlock();
            var allAffectedStatements = new HashSet<StatementSyntax>(matches.SelectMany(expr => expr.GetAncestorsOrThis<StatementSyntax>()));
            var firstStatementAffectedInBlock = oldInnerMostCommonBlock.Statements.First(allAffectedStatements.Contains);

            var firstStatementAffectedIndex = oldInnerMostCommonBlock.Statements.IndexOf(firstStatementAffectedInBlock);

            var newInnerMostBlock = Rewrite(
                document, expression, newLocalName, document, oldInnerMostCommonBlock, allOccurrences, cancellationToken);

            var statements = new List<StatementSyntax>();
            statements.AddRange(newInnerMostBlock.Statements.Take(firstStatementAffectedIndex));
            statements.Add(declarationStatement);
            statements.AddRange(newInnerMostBlock.Statements.Skip(firstStatementAffectedIndex));

            var finalInnerMostBlock = newInnerMostBlock.WithStatements(
                SyntaxFactory.List<StatementSyntax>(statements));

            var newRoot = document.Root.ReplaceNode(oldInnerMostCommonBlock, finalInnerMostBlock);
            return document.Document.WithSyntaxRoot(newRoot);
        }
예제 #34
0
        public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            var info = _semanticModel.GetTypeInfo(node.Declaration.Type);
            if (!info.Type.IsScriptSymbol())
            {
                this.AppendCompileIssue(node, IssueType.Error, IssueId.UseNonScript, info.Type);
            }

            _output.TrivialWrite("var ");
            this.MakeLocalVariableList(node.Declaration);

            return node;
        }
예제 #35
0
        internal BoundStatement BindLocalDeclarationStatement(LocalDeclarationStatementSyntax node, DiagnosticBag diagnostics)
        {
            var binder = GetBinder(node);
            Debug.Assert(binder != null);

            BoundStatement bound;
            bound = binder.BindDeclarationStatementParts(node, diagnostics);
            return binder.WrapWithVariablesIfAny(node, bound);
        }
 private static SyntaxList<StatementSyntax> CreateNewStatementList(
     SyntaxList<StatementSyntax> oldStatements,
     LocalDeclarationStatementSyntax localDeclaration,
     StatementSyntax newStatement,
     int statementIndex)
 {
     return oldStatements.Take(statementIndex)
                         .Concat(localDeclaration.WithLeadingTrivia(oldStatements.Skip(statementIndex).First().GetLeadingTrivia()))
                         .Concat(newStatement.WithoutLeadingTrivia())
                         .Concat(oldStatements.Skip(statementIndex + 1))
                         .ToSyntaxList();
 }
        private Document IntroduceLocalForSingleOccurrenceIntoBlock(
            SemanticDocument document,
            ExpressionSyntax expression,
            NameSyntax localName,
            LocalDeclarationStatementSyntax localDeclaration,
            bool allOccurrences,
            CancellationToken cancellationToken)
        {
            var oldStatement = expression.GetAncestorOrThis<StatementSyntax>();
            var newStatement = Rewrite(
                document, expression, localName, document, oldStatement, allOccurrences, cancellationToken);

            if (oldStatement.IsParentKind(SyntaxKind.Block))
            {
                var oldBlock = oldStatement.Parent as BlockSyntax;
                var statementIndex = oldBlock.Statements.IndexOf(oldStatement);

                var newBlock = oldBlock.WithStatements(CreateNewStatementList(
                    oldBlock.Statements, localDeclaration, newStatement, statementIndex));

                var newRoot = document.Root.ReplaceNode(oldBlock, newBlock);
                return document.Document.WithSyntaxRoot(newRoot);
            }
            else if (oldStatement.IsParentKind(SyntaxKind.SwitchSection))
            {
                var oldSwitchSection = oldStatement.Parent as SwitchSectionSyntax;
                var statementIndex = oldSwitchSection.Statements.IndexOf(oldStatement);

                var newSwitchSection = oldSwitchSection.WithStatements(CreateNewStatementList(
                    oldSwitchSection.Statements, localDeclaration, newStatement, statementIndex));

                var newRoot = document.Root.ReplaceNode(oldSwitchSection, newSwitchSection);
                return document.Document.WithSyntaxRoot(newRoot);
            }
            else
            {
                // we need to introduce a block to put the original statement, along with
                // the statement we're generating
                var newBlock = SyntaxFactory.Block(localDeclaration, newStatement).WithAdditionalAnnotations(Formatter.Annotation);

                var newRoot = document.Root.ReplaceNode(oldStatement, newBlock);
                return document.Document.WithSyntaxRoot(newRoot);
            }
        }