diff --git a/eng/config/BannedSymbols.txt b/eng/config/BannedSymbols.txt
index 8558e121b5dc2..9c707886b0b18 100644
--- a/eng/config/BannedSymbols.txt
+++ b/eng/config/BannedSymbols.txt
@@ -47,14 +47,14 @@ M:Microsoft.CodeAnalysis.Editing.SyntaxEditor.#ctor(Microsoft.CodeAnalysis.Synta
M:Microsoft.CodeAnalysis.FileTextLoader.#ctor(System.String,System.Text.Encoding); use WorkspaceFileTextLoader that calls on ITextFactoryService to create SourceText
M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.SyntaxTree(Microsoft.CodeAnalysis.SyntaxNode,Microsoft.CodeAnalysis.ParseOptions,System.String,System.Text.Encoding); Use CSharpSyntaxTree sublass that takes checksum algorithm
M:Microsoft.CodeAnalysis.CSharp.SyntaxFactory.ParseSyntaxTree(System.String,Microsoft.CodeAnalysis.ParseOptions,System.String,System.Text.Encoding,System.Threading.CancellationToken); Use CSharpSyntaxTree sublass that takes checksum algorithm
-M:Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.CreateWithoutClone(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode); Use CSharpSyntaxTree sublass that takes checksum algorithm
+M:Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.CreateWithoutClone(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode,Microsoft.CodeAnalysis.CSharp.CSharpParseOptions); Use CSharpSyntaxTree sublass that takes checksum algorithm
M:Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.Create(Microsoft.CodeAnalysis.CSharp.CSharpSyntaxNode, Microsoft.CodeAnalysis.CSharp.CSharpParseOptions options, System.String path, System.Text.Encoding encoding); Use CSharpSyntaxTree sublass that takes checksum algorithm
M:Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(System.String,Microsoft.CodeAnalysis.CSharp.CSharpParseOptions,System.String,System.Text.Encoding,System.Threading.CancellationToken); Use API that takes SourceText
M:Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(System.String,Microsoft.CodeAnalysis.CSharp.CSharpParseOptions,System.String,System.Text.Encoding,System.Collections.Immutable.ImmutableDictionary{System.String,Microsoft.CodeAnalysis.ReportDiagnostic},System.Nullable{System.Boolean},System.Threading.CancellationToken); Use API that takes SourceText
M:Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.SyntaxTree(Microsoft.CodeAnalysis.SyntaxNode,Microsoft.CodeAnalysis.ParseOptions,System.String,System.Text.Encoding); Use VisualBasicSyntaxTree sublass that takes checksum algorithm
M:Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.ParseSyntaxTree(System.String,Microsoft.CodeAnalysis.ParseOptions,System.String,System.Text.Encoding,System.Threading.CancellationToken); Use overload with SourceText
M:Microsoft.CodeAnalysis.VisualBasic.SyntaxFactory.ParseSyntaxTree(System.String,Microsoft.CodeAnalysis.ParseOptions,System.String,System.Text.Encoding,System.Collections.Immutable.ImmutableDictionary{System.String,Microsoft.CodeAnalysis.ReportDiagnostic},System.Threading.CancellationToken); Use overload with SourceText
-M:Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree.CreateWithoutClone(Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxNode); Use VisualBasicSyntaxTree sublass that takes checksum algorithm
+M:Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree.CreateWithoutClone(Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxNode,Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions); Use VisualBasicSyntaxTree sublass that takes checksum algorithm
M:Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree.Create(Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxNode,Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions,System.String,System.Text.Encoding,System.Collections.Immutable.ImmutableDictionary{System.String,Microsoft.CodeAnalysis.ReportDiagnostic}); Use VisualBasicSyntaxTree sublass that takes checksum algorithm
M:Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree.Create(Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxNode,Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions,System.String,System.Text.Encoding); Use VisualBasicSyntaxTree sublass that takes checksum algorithm
M:Microsoft.CodeAnalysis.VisualBasic.VisualBasicSyntaxTree.ParseText(System.String,Microsoft.CodeAnalysis.VisualBasic.VisualBasicParseOptions,System.String,System.Text.Encoding,System.Collections.Immutable.ImmutableDictionary{System.String,Microsoft.CodeAnalysis.ReportDiagnostic},System.Threading.CancellationToken); Use overload with SourceText
diff --git a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxNode.cs b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxNode.cs
index 3b09234ad0c18..3f27691d9e952 100644
--- a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxNode.cs
+++ b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxNode.cs
@@ -9,9 +9,7 @@
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.PooledObjects;
-using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
{
@@ -73,8 +71,8 @@ private static SyntaxTree ComputeSyntaxTree(CSharpSyntaxNode node)
if (parent == null)
{
// set the tree on the root node atomically
-#pragma warning disable RS0030 // Do not use banned APIs (CreateWithoutClone is intended to be used from this call site only)
- Interlocked.CompareExchange(ref node._syntaxTree, CSharpSyntaxTree.CreateWithoutClone(node), null);
+#pragma warning disable RS0030 // Do not use banned APIs (CreateWithoutClone is intended to be used from this call site)
+ Interlocked.CompareExchange(ref node._syntaxTree, CSharpSyntaxTree.CreateWithoutClone(node, CSharpParseOptions.Default), null);
#pragma warning restore
tree = node._syntaxTree;
break;
diff --git a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.cs b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.cs
index 6cf328da50821..103c8509f5c28 100644
--- a/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.cs
+++ b/src/Compilers/CSharp/Portable/Syntax/CSharpSyntaxTree.cs
@@ -8,8 +8,6 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -390,10 +388,10 @@ internal static SyntaxTree CreateForDebugger(CSharpSyntaxNode root, SourceText t
/// Internal helper for class to create a new syntax tree rooted at the given root node.
/// This method does not create a clone of the given root, but instead preserves it's reference identity.
///
- /// NOTE: This method is only intended to be used from property.
+ /// NOTE: This method is only intended to be used from property and SyntaxFactory.Parse* methods.
/// NOTE: Do not use this method elsewhere, instead use method for creating a syntax tree.
///
- internal static SyntaxTree CreateWithoutClone(CSharpSyntaxNode root)
+ internal static SyntaxTree CreateWithoutClone(CSharpSyntaxNode root, CSharpParseOptions options)
{
Debug.Assert(root != null);
@@ -402,7 +400,7 @@ internal static SyntaxTree CreateWithoutClone(CSharpSyntaxNode root)
encodingOpt: null,
checksumAlgorithm: SourceHashAlgorithm.Sha1,
path: "",
- options: CSharpParseOptions.Default,
+ options: options,
root: root,
directives: default,
diagnosticOptions: null,
diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs
index a1cbe33a1b30f..5b57505194954 100644
--- a/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs
+++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxFactory.cs
@@ -1694,7 +1694,7 @@ public static NameSyntax ParseName(string text, int offset = 0, bool consumeFull
{
var node = parser.ParseName();
if (consumeFullText) node = parser.ConsumeUnexpectedTokens(node);
- return (NameSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
}
}
@@ -1718,7 +1718,7 @@ public static TypeSyntax ParseTypeName(string text, int offset = 0, ParseOptions
{
var node = parser.ParseTypeName();
if (consumeFullText) node = parser.ConsumeUnexpectedTokens(node);
- return (TypeSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
}
}
@@ -1737,7 +1737,7 @@ public static ExpressionSyntax ParseExpression(string text, int offset = 0, Pars
{
var node = parser.ParseExpression();
if (consumeFullText) node = parser.ConsumeUnexpectedTokens(node);
- return (ExpressionSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
}
}
@@ -1756,7 +1756,7 @@ public static StatementSyntax ParseStatement(string text, int offset = 0, ParseO
{
var node = parser.ParseStatement();
if (consumeFullText) node = parser.ConsumeUnexpectedTokens(node);
- return (StatementSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
}
}
@@ -1780,7 +1780,7 @@ public static StatementSyntax ParseStatement(string text, int offset = 0, ParseO
return null;
}
- return (MemberDeclarationSyntax)(consumeFullText ? parser.ConsumeUnexpectedTokens(node) : node).CreateRed();
+ return CreateRed(consumeFullText ? parser.ConsumeUnexpectedTokens(node) : node, lexer.Options);
}
}
@@ -1800,7 +1800,7 @@ public static CompilationUnitSyntax ParseCompilationUnit(string text, int offset
using (var parser = MakeParser(lexer))
{
var node = parser.ParseCompilationUnit();
- return (CompilationUnitSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
}
}
@@ -1819,7 +1819,7 @@ public static ParameterListSyntax ParseParameterList(string text, int offset = 0
{
var node = parser.ParseParenthesizedParameterList(forExtension: false);
if (consumeFullText) node = parser.ConsumeUnexpectedTokens(node);
- return (ParameterListSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
}
}
@@ -1838,7 +1838,7 @@ public static BracketedParameterListSyntax ParseBracketedParameterList(string te
{
var node = parser.ParseBracketedParameterList();
if (consumeFullText) node = parser.ConsumeUnexpectedTokens(node);
- return (BracketedParameterListSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
}
}
@@ -1857,7 +1857,7 @@ public static ArgumentListSyntax ParseArgumentList(string text, int offset = 0,
{
var node = parser.ParseParenthesizedArgumentList();
if (consumeFullText) node = parser.ConsumeUnexpectedTokens(node);
- return (ArgumentListSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
}
}
@@ -1876,7 +1876,7 @@ public static BracketedArgumentListSyntax ParseBracketedArgumentList(string text
{
var node = parser.ParseBracketedArgumentList();
if (consumeFullText) node = parser.ConsumeUnexpectedTokens(node);
- return (BracketedArgumentListSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
}
}
@@ -1902,7 +1902,18 @@ public static BracketedArgumentListSyntax ParseBracketedArgumentList(string text
annotations: null);
if (consumeFullText)
node = parser.ConsumeUnexpectedTokens(node);
- return (AttributeArgumentListSyntax)node.CreateRed();
+ return CreateRed(node, lexer.Options);
+ }
+
+ private static TSyntax CreateRed(InternalSyntax.CSharpSyntaxNode green, CSharpParseOptions options)
+ where TSyntax : CSharpSyntaxNode
+ {
+ var red = (TSyntax)green.CreateRed();
+ Debug.Assert(red._syntaxTree is null);
+#pragma warning disable RS0030 // Do not use banned APIs (CreateWithoutClone is intended to be used from this call site)
+ red._syntaxTree = CSharpSyntaxTree.CreateWithoutClone(red, options);
+#pragma warning restore
+ return red;
}
///
diff --git a/src/Compilers/CSharp/Test/Semantic/Semantics/SyntaxTreeRootTests.cs b/src/Compilers/CSharp/Test/Semantic/Semantics/SyntaxTreeRootTests.cs
index a5bdfcbdb0f5a..43b0b048eb0f2 100644
--- a/src/Compilers/CSharp/Test/Semantic/Semantics/SyntaxTreeRootTests.cs
+++ b/src/Compilers/CSharp/Test/Semantic/Semantics/SyntaxTreeRootTests.cs
@@ -4,17 +4,12 @@
#nullable disable
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.CodeAnalysis.Text;
using System;
-using System.Collections.Generic;
using System.Linq;
using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using Xunit;
-using Microsoft.CodeAnalysis.CSharp.Symbols;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
+using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.Semantics
{
@@ -32,7 +27,7 @@ public void SyntaxTreeCreateAcceptsAnySyntaxNode()
public void SyntaxTreeCreateWithoutCloneAcceptsAnySyntaxNode()
{
var node = SyntaxFactory.CatchClause(SyntaxFactory.CatchDeclaration(SyntaxFactory.ParseTypeName(typeof(InvalidOperationException).Name)), null, SyntaxFactory.Block());
- var tree = CSharpSyntaxTree.CreateWithoutClone(node);
+ var tree = CSharpSyntaxTree.CreateWithoutClone(node, CSharpParseOptions.Default);
CheckTree(tree);
}
diff --git a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs
index 49178bb9c5a9e..bc2e73ce0a952 100644
--- a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs
+++ b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxFactoryTests.cs
@@ -9,11 +9,11 @@
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Xunit;
using InternalSyntax = Microsoft.CodeAnalysis.CSharp.Syntax.InternalSyntax;
-using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
@@ -678,5 +678,41 @@ public void TestParseNameWithOptions()
// unsafe class C { delegate* x; }
Diagnostic(ErrorCode.WRN_UnreferencedField, "x").WithArguments("C.x").WithLocation(1, 34));
}
+
+ [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78510")]
+ public void TestParseMethodsKeepParseOptionsInTheTree()
+ {
+ var parseOptions = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest);
+
+ var argList = SyntaxFactory.ParseArgumentList("", options: parseOptions);
+ Assert.Same(parseOptions, argList.SyntaxTree.Options);
+
+ var attrArgList = SyntaxFactory.ParseAttributeArgumentList("", options: parseOptions);
+ Assert.Same(parseOptions, attrArgList.SyntaxTree.Options);
+
+ var bracketedArgList = SyntaxFactory.ParseBracketedArgumentList("", options: parseOptions);
+ Assert.Same(parseOptions, bracketedArgList.SyntaxTree.Options);
+
+ var bracketedParamList = SyntaxFactory.ParseBracketedParameterList("", options: parseOptions);
+ Assert.Same(parseOptions, bracketedParamList.SyntaxTree.Options);
+
+ var compUnit = SyntaxFactory.ParseCompilationUnit("", options: parseOptions);
+ Assert.Same(parseOptions, compUnit.SyntaxTree.Options);
+
+ var expr = SyntaxFactory.ParseExpression("", options: parseOptions);
+ Assert.Same(parseOptions, expr.SyntaxTree.Options);
+
+ var memberDecl = SyntaxFactory.ParseMemberDeclaration("public", options: parseOptions);
+ Assert.Same(parseOptions, memberDecl.SyntaxTree.Options);
+
+ var paramList = SyntaxFactory.ParseParameterList("", options: parseOptions);
+ Assert.Same(parseOptions, paramList.SyntaxTree.Options);
+
+ var statement = SyntaxFactory.ParseStatement("", options: parseOptions);
+ Assert.Same(parseOptions, statement.SyntaxTree.Options);
+
+ var typeName = SyntaxFactory.ParseTypeName("", options: parseOptions);
+ Assert.Same(parseOptions, typeName.SyntaxTree.Options);
+ }
}
}
diff --git a/src/Compilers/VisualBasic/Portable/Parser/Parser.vb b/src/Compilers/VisualBasic/Portable/Parser/Parser.vb
index 2b7dc24d71d1f..7a2a53a2413a0 100644
--- a/src/Compilers/VisualBasic/Portable/Parser/Parser.vb
+++ b/src/Compilers/VisualBasic/Portable/Parser/Parser.vb
@@ -70,6 +70,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
End If
End Sub
+ Friend ReadOnly Property Options As VisualBasicParseOptions
+ Get
+ Return _scanner.Options
+ End Get
+ End Property
+
Friend ReadOnly Property IsScript As Boolean
Get
Return _scanner.Options.Kind = SourceCodeKind.Script
diff --git a/src/Compilers/VisualBasic/Portable/Syntax/SyntaxNodeFactories.vb b/src/Compilers/VisualBasic/Portable/Syntax/SyntaxNodeFactories.vb
index 78a47f4eb237c..87034af48384e 100644
--- a/src/Compilers/VisualBasic/Portable/Syntax/SyntaxNodeFactories.vb
+++ b/src/Compilers/VisualBasic/Portable/Syntax/SyntaxNodeFactories.vb
@@ -7,15 +7,15 @@
' code-generated into SyntaxNodes.vb, but some are easier to hand-write.
'-----------------------------------------------------------------------------------------------------------
-Imports System.Threading
+Imports System.Collections.Immutable
+Imports System.ComponentModel
Imports System.Text
+Imports System.Threading
+Imports Microsoft.CodeAnalysis.Syntax
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.VisualBasic.SyntaxFacts
Imports InternalSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
-Imports Microsoft.CodeAnalysis.Syntax
-Imports System.Collections.Immutable
-Imports System.ComponentModel
Namespace Microsoft.CodeAnalysis.VisualBasic
@@ -186,7 +186,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
disallowGenericArgumentsOnLastQualifiedName:=False,
allowEmptyGenericArguments:=True,
allowedEmptyGenericArguments:=True)
- Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), NameSyntax)
+ Return CreateRed(Of NameSyntax)(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node), p.Options)
End Using
End Function
@@ -196,10 +196,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' The input string
''' The starting offset in the string
Public Shared Function ParseTypeName(text As String, Optional offset As Integer = 0, Optional options As ParseOptions = Nothing, Optional consumeFullText As Boolean = True) As TypeSyntax
- Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), If(DirectCast(options, VisualBasicParseOptions), VisualBasicParseOptions.Default))
+ Dim vbOptions As VisualBasicParseOptions = DirectCast(options, VisualBasicParseOptions)
+ Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), If(vbOptions, VisualBasicParseOptions.Default))
p.GetNextToken()
Dim node = p.ParseGeneralType()
- Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), TypeSyntax)
+ If consumeFullText Then
+ node = p.ConsumeUnexpectedTokens(node)
+ End If
+ Return CreateRed(Of TypeSyntax)(node, p.Options)
End Using
End Function
@@ -223,7 +227,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
p.GetNextToken()
Dim node = p.ParseExpression()
- Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), ExpressionSyntax)
+ Return CreateRed(Of ExpressionSyntax)(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node), p.Options)
End Using
End Function
@@ -235,7 +239,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Shared Function ParseExecutableStatement(text As String, Optional offset As Integer = 0, Optional consumeFullText As Boolean = True) As StatementSyntax
Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
Dim node = p.ParseExecutableStatement()
- Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), StatementSyntax)
+ Return CreateRed(Of StatementSyntax)(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node), p.Options)
End Using
End Function
@@ -246,7 +250,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' The starting offset in the string
Public Shared Function ParseCompilationUnit(text As String, Optional offset As Integer = 0, Optional options As VisualBasicParseOptions = Nothing) As CompilationUnitSyntax
Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), If(options, VisualBasicParseOptions.Default))
- Return DirectCast(p.ParseCompilationUnit().CreateRed(Nothing, 0), CompilationUnitSyntax)
+ Dim node = p.ParseCompilationUnit()
+ Return CreateRed(Of CompilationUnitSyntax)(node, p.Options)
End Using
End Function
@@ -259,7 +264,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
p.GetNextToken()
Dim node = p.ParseParameterList()
- Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), ParameterListSyntax)
+ Return CreateRed(Of ParameterListSyntax)(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node), p.Options)
End Using
End Function
@@ -272,7 +277,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
p.GetNextToken()
Dim node = p.ParseParenthesizedArguments()
- Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), ArgumentListSyntax)
+ Return CreateRed(Of ArgumentListSyntax)(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node), p.Options)
End Using
End Function
@@ -298,15 +303,24 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim xmlName = InternalSyntax.SyntaxFactory.XmlName(
Nothing, InternalSyntax.SyntaxFactory.XmlNameToken(parentElementName, SyntaxKind.XmlNameToken, Nothing, Nothing))
- Return DirectCast(
- parser.ParseXmlAttribute(
+ Dim xmlAttribute = parser.ParseXmlAttribute(
requireLeadingWhitespace:=False,
AllowNameAsExpression:=False,
- xmlElementName:=xmlName).CreateRed(Nothing, 0), BaseXmlAttributeSyntax)
+ xmlElementName:=xmlName)
+ Return CreateRed(Of BaseXmlAttributeSyntax)(xmlAttribute, scanner.Options)
End Using
End Using
End Function
+ Private Shared Function CreateRed(Of TSyntax As VisualBasicSyntaxNode)(green As InternalSyntax.VisualBasicSyntaxNode, options As VisualBasicParseOptions) As TSyntax
+ Dim red = DirectCast(green.CreateRed(), TSyntax)
+ Debug.Assert(red._syntaxTree Is Nothing)
+#Disable Warning RS0030 ' Do not use banned APIs (CreateWithoutClone is intended to be used from this call site)
+ red._syntaxTree = VisualBasicSyntaxTree.CreateWithoutClone(red, options)
+#Enable Warning RS0030
+ Return red
+ End Function
+
#End Region
#Region "TokenFactories"
diff --git a/src/Compilers/VisualBasic/Portable/Syntax/VisualBasicSyntaxNode.vb b/src/Compilers/VisualBasic/Portable/Syntax/VisualBasicSyntaxNode.vb
index ae5c84381bf04..3d8e5229b22de 100644
--- a/src/Compilers/VisualBasic/Portable/Syntax/VisualBasicSyntaxNode.vb
+++ b/src/Compilers/VisualBasic/Portable/Syntax/VisualBasicSyntaxNode.vb
@@ -2,12 +2,8 @@
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
-Imports System.Collections.Immutable
Imports System.Collections.ObjectModel
-Imports System.ComponentModel
-Imports System.Reflection
Imports System.Threading
-Imports Microsoft.CodeAnalysis.ErrorReporting
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
@@ -70,8 +66,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If tree Is Nothing Then
Debug.Assert(rootCandidate IsNot Nothing)
-#Disable Warning RS0030 ' Do not use banned APIs (CreateWithoutClone is intended to be used from this call site only)
- tree = VisualBasicSyntaxTree.CreateWithoutClone(DirectCast(rootCandidate, VisualBasicSyntaxNode))
+#Disable Warning RS0030 ' Do not use banned APIs (CreateWithoutClone is intended to be used from this call site)
+ tree = VisualBasicSyntaxTree.CreateWithoutClone(DirectCast(rootCandidate, VisualBasicSyntaxNode), VisualBasicParseOptions.Default)
#Enable Warning RS0030
End If
diff --git a/src/Compilers/VisualBasic/Portable/Syntax/VisualBasicSyntaxTree.vb b/src/Compilers/VisualBasic/Portable/Syntax/VisualBasicSyntaxTree.vb
index 04ed895f802ff..2f1d0ef1c6f64 100644
--- a/src/Compilers/VisualBasic/Portable/Syntax/VisualBasicSyntaxTree.vb
+++ b/src/Compilers/VisualBasic/Portable/Syntax/VisualBasicSyntaxTree.vb
@@ -210,10 +210,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' Internal helper for class to create a new syntax tree rooted at the given root node.
''' This method does not create a clone of the given root, but instead preserves its reference identity.
'''
- ''' NOTE: This method is only intended to be used from property.
+ ''' NOTE: This method is only intended to be used from property and SyntaxFactory.Parse* methods.
''' NOTE: Do not use this method elsewhere, instead use method for creating a syntax tree.
'''
- Friend Shared Function CreateWithoutClone(root As VisualBasicSyntaxNode) As SyntaxTree
+ Friend Shared Function CreateWithoutClone(root As VisualBasicSyntaxNode, options As VisualBasicParseOptions) As SyntaxTree
Debug.Assert(root IsNot Nothing)
Return New ParsedSyntaxTree(
@@ -221,7 +221,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
path:="",
encodingOpt:=Nothing,
checksumAlgorithm:=SourceHashAlgorithm.Sha1,
- options:=VisualBasicParseOptions.Default,
+ options:=options,
syntaxRoot:=root,
isMyTemplate:=False,
diagnosticOptions:=Nothing,
diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ScriptSemanticsTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ScriptSemanticsTests.vb
index 12c757cc2435f..65edb50b216ab 100644
--- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/ScriptSemanticsTests.vb
+++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/ScriptSemanticsTests.vb
@@ -45,31 +45,17 @@ F(Function()
Dim semanticModel = compilation.GetSemanticModel(syntaxTree, True)
Dim node5 As MemberAccessExpressionSyntax = ErrorTestsGetNode(syntaxTree)
Assert.Equal("WriteLine", node5.Name.ToString())
- Assert.Null(semanticModel.GetSymbolInfo(node5.Name).Symbol)
+ Assert.Equal("Sub System.Console.WriteLine(value As System.Int32)", semanticModel.GetSymbolInfo(node5.Name).Symbol.ToTestDisplayString())
- compilation.AssertTheseDiagnostics(
-
-BC30420: 'Sub Main' was not found in 'Errors_01'.
-BC30001: Statement is not valid in a namespace.
-System.Console.WriteLine(1)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- )
+ compilation.AssertTheseDiagnostics()
compilation = CreateCompilationWithMscorlib461({syntaxTree}, options:=TestOptions.ReleaseExe.WithScriptClassName("Script"), assemblyName:="Errors_01")
semanticModel = compilation.GetSemanticModel(syntaxTree, True)
node5 = ErrorTestsGetNode(syntaxTree)
Assert.Equal("WriteLine", node5.Name.ToString())
- Assert.Null(semanticModel.GetSymbolInfo(node5.Name).Symbol)
+ Assert.Equal("Sub System.Console.WriteLine(value As System.Int32)", semanticModel.GetSymbolInfo(node5.Name).Symbol.ToTestDisplayString())
- compilation.AssertTheseDiagnostics(
-
-BC30420: 'Sub Main' was not found in 'Errors_01'.
-BC30001: Statement is not valid in a namespace.
-System.Console.WriteLine(1)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- )
+ compilation.AssertTheseDiagnostics()
syntaxTree = SyntaxFactory.ParseSyntaxTree(code, options:=New VisualBasicParseOptions(kind:=SourceCodeKind.Script))
compilation = CreateCompilationWithMscorlib461AndVBRuntime({syntaxTree}, options:=TestOptions.ReleaseExe)
@@ -129,6 +115,7 @@ BC2014: the value 'Nothing' is invalid for option 'ScriptClassName'
+
Public Sub Errors_02()
Dim compilationUnit = VisualBasic.SyntaxFactory.ParseCompilationUnit("System.Console.WriteLine(1)", options:=New VisualBasicParseOptions(kind:=SourceCodeKind.Script))
Dim syntaxTree1 = compilationUnit.SyntaxTree
@@ -138,33 +125,41 @@ BC2014: the value 'Nothing' is invalid for option 'ScriptClassName'
Dim node2 As MemberAccessExpressionSyntax = ErrorTestsGetNode(syntaxTree2)
Assert.Equal("WriteLine", node2.Name.ToString())
- Dim compilation = CreateCompilationWithMscorlib461({syntaxTree1, syntaxTree2})
- Dim semanticModel1 = compilation.GetSemanticModel(syntaxTree1, True)
- Dim semanticModel2 = compilation.GetSemanticModel(syntaxTree2, True)
- Assert.Null(semanticModel1.GetSymbolInfo(node1.Name).Symbol)
- Assert.Equal("Sub System.Console.WriteLine(value As System.Int32)", semanticModel2.GetSymbolInfo(node2.Name).Symbol.ToTestDisplayString())
+ Assert.Throws(Of InvalidOperationException)(
+ Sub()
+ Dim compilation = CreateCompilationWithMscorlib461({syntaxTree1, syntaxTree2})
+ Dim semanticModel1 = compilation.GetSemanticModel(syntaxTree1, True)
+ Dim semanticModel2 = compilation.GetSemanticModel(syntaxTree2, True)
- compilation.AssertTheseDiagnostics(
+ Assert.Null(semanticModel1.GetSymbolInfo(node1.Name).Symbol)
+ Assert.Equal("Sub System.Console.WriteLine(value As System.Int32)", semanticModel2.GetSymbolInfo(node2.Name).Symbol.ToTestDisplayString())
+
+ Compilation.AssertTheseDiagnostics(
BC30001: Statement is not valid in a namespace.
System.Console.WriteLine(1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
- )
+ )
+ End Sub)
- compilation = CreateCompilationWithMscorlib461({syntaxTree2, syntaxTree1})
- semanticModel1 = compilation.GetSemanticModel(syntaxTree1, True)
- semanticModel2 = compilation.GetSemanticModel(syntaxTree2, True)
- Assert.Null(semanticModel1.GetSymbolInfo(node1.Name).Symbol)
- Assert.Equal("Sub System.Console.WriteLine(value As System.Int32)", semanticModel2.GetSymbolInfo(node2.Name).Symbol.ToTestDisplayString())
+ Assert.Throws(Of InvalidOperationException)(
+ Sub()
+ Dim compilation = CreateCompilationWithMscorlib461({syntaxTree2, syntaxTree1})
+ Dim semanticModel1 = compilation.GetSemanticModel(syntaxTree1, True)
+ Dim semanticModel2 = compilation.GetSemanticModel(syntaxTree2, True)
- compilation.AssertTheseDiagnostics(
-
+ Assert.Null(semanticModel1.GetSymbolInfo(node1.Name).Symbol)
+ Assert.Equal("Sub System.Console.WriteLine(value As System.Int32)", semanticModel2.GetSymbolInfo(node2.Name).Symbol.ToTestDisplayString())
+
+ Compilation.AssertTheseDiagnostics(
+
BC30001: Statement is not valid in a namespace.
System.Console.WriteLine(1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
- )
+ )
+ End Sub)
End Sub
Private Shared Function ErrorTestsGetNode(syntaxTree As SyntaxTree) As MemberAccessExpressionSyntax
diff --git a/src/Compilers/VisualBasic/Test/Semantic/Semantics/SyntaxTreeRootTests.vb b/src/Compilers/VisualBasic/Test/Semantic/Semantics/SyntaxTreeRootTests.vb
index 76cdf5c630995..7024c5bc413f6 100644
--- a/src/Compilers/VisualBasic/Test/Semantic/Semantics/SyntaxTreeRootTests.vb
+++ b/src/Compilers/VisualBasic/Test/Semantic/Semantics/SyntaxTreeRootTests.vb
@@ -3,7 +3,6 @@
' See the LICENSE file in the project root for more information.
Imports System.Reflection
-Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
@@ -19,7 +18,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics
Public Sub SyntaxTreeCreateWithoutCloneAcceptsAnySyntaxNode()
Dim node As VisualBasicSyntaxNode = SyntaxFactory.CatchStatement(SyntaxFactory.IdentifierName("Goo"), SyntaxFactory.SimpleAsClause(SyntaxFactory.ParseTypeName(GetType(InvalidOperationException).Name)), Nothing)
- Dim tree = VisualBasicSyntaxTree.CreateWithoutClone(node)
+ Dim tree = VisualBasicSyntaxTree.CreateWithoutClone(node, VisualBasicParseOptions.Default)
CheckTree(tree)
End Sub
diff --git a/src/Compilers/VisualBasic/Test/Syntax/Syntax/SyntaxFactoryTests.vb b/src/Compilers/VisualBasic/Test/Syntax/Syntax/SyntaxFactoryTests.vb
index 62f091c35ccd5..bb08faf2730a6 100644
--- a/src/Compilers/VisualBasic/Test/Syntax/Syntax/SyntaxFactoryTests.vb
+++ b/src/Compilers/VisualBasic/Test/Syntax/Syntax/SyntaxFactoryTests.vb
@@ -123,5 +123,16 @@ Integer
Dim type2 = SyntaxFactory.ParseTypeName(code, options:=options)
Assert.Equal("Integer", type2.ToString())
End Sub
+
+
+ Public Shared Sub TestParseMethodsKeepParseOptionsInTheTree()
+ Dim parseOptions = VisualBasicParseOptions.Default.WithLanguageVersion(LanguageVersion.Latest)
+
+ Dim compUnit = SyntaxFactory.ParseCompilationUnit("", options:=parseOptions)
+ Assert.Same(parseOptions, compUnit.SyntaxTree.Options)
+
+ Dim typeName = SyntaxFactory.ParseTypeName("", options:=parseOptions)
+ Assert.Same(parseOptions, typeName.SyntaxTree.Options)
+ End Sub
End Class
End Namespace