1. 07 5月, 2014 9 次提交
  2. 06 5月, 2014 5 次提交
    • A
      Migrated state of “Declaration Expressions” implementation equivalent to... · 2ea2068f
      AlekseyTs 提交于
      Migrated state of “Declaration Expressions” implementation equivalent to https://roslyn.codeplex.com/SourceControl/changeset/b7fd08a5695e21cd4d23b8b70815c53656dab65f. (changeset 1249879)
      2ea2068f
    • T
      Remove unused/unnecessary interfaces. · f29eb57a
      TomasMatousek 提交于
      Use ImmutableArray instead if IEnumerable. (changeset 1249786)
      f29eb57a
    • A
      Migrated state of “Primary Constructors” implementation equivalent to... · bdc71524
      AlekseyTs 提交于
      Migrated state of “Primary Constructors” implementation equivalent to https://roslyn.codeplex.com/SourceControl/changeset/af3db25146a74523fbb2cf11ef00ddec6c0c3690. (changeset 1249690)
      bdc71524
    • T
      In C# lowering of async method stored the state machine type on... · 65f24c70
      TomasMatousek 提交于
      In C# lowering of async method stored the state machine type on SourceMethodSymbol so it can later be used when emitting synthesized attributes of the method. This may cause issues when emitting the same compilation twice with different options that affect the state machine type.
           Instead we should store the state machine type to the current PEModuleBuilder. Rather then actually storing it there and adding a dependency on PEModuleBuilder to the attribute generation this change introduces ModuleCompilationState (similar to TypeCompilationState) and threads that one.
           This type is designed to be mutable during compilation (lowering) and immutable during emit. The idea is that all data currently stored in PEModuleBuilder that are produced during compilation and only read in emit could be moved there. Only emit specific data would remain on PEModuleBuilder.
      
           Also refactors Compilation.Compile to remove some duplication and make it cleaner.
       (changeset 1249664)
      65f24c70
    • V
      Implementation of conditional access operators - ?. and ?[] · 6f2e0b6d
      VSadov 提交于
       Change Description:
      
           Implementation of conditional access operators ( ?. and ?[] )
      
           The grammar roughly looks like:
      
           expr ::= | ...
                    | expr ? tail
      
           tail ::= | tailopt . id
           tail ::= | tailopt .$ id                        <---   this is NYI in this change
                    | tailopt [ expr-args ]
                    | tail ( expr-args )
      
           Note that the tail isn’t optional for invocation: there is no ?(…) operator.
      
           Interesting implementation points:
      
           == Parsing/syntax
      
           Syntax tree is right associative – it has the same topology as in the grammar. However I did not create special variants for all the kinds of syntax that could be produced by the parsing of the tail of accessors.
           I just use regular syntax nodes with exception of the topmost node that is the conditional access operator itself and the lower-leftmost node that textually starts the accessor tail.
      
           The root node looks like –
      
           ConditionalAccessExpression
           {
              ExpressionSyntax Expression;
              SyntaxToken OperatorToken;                  // always “?”
              ExpressionSyntax WhenNotNull;              // by analogy with conditional expression which uses WhenTrue
           }
      
           WhenNotNull is an ExpressionSyntax that represent the sequence of postfix operations conditionally applied to the Expression. These are regular InvocationExpressions, MemberAccesses, ElementAcesses – whatever postfix operators we have.
      
           The only special part about WhenNotNull is that the low-leftmost expression child is one of 2 special “binding” nodes – MemberBindingExpression, ElementBindingExpression.
      
           Binding expressions are entities which can start the chain of WhenNotNull . Textually they look like  -  “ .SimpleName“ ,  “[argList]” or “$Name” (when $ accessor is supported).
           Note that there is no InvocationBinding, since we do not allow () to start the chain of applications – you cannot do “a?(arg)”.
           The binding expression syntaxes are basically versions of corresponding member/element/dollar access expressions without receivers.
      
           R?.a.b(x).c
      
           Would parse as
      
               ConditionalAccess
             /         |         \
           R           ?          MemberAccess
                                       /    |   \
                             Invocation     .     c
                            /           \
                      MemberAccess       ArgList{( x )}
                     /        |    \
           MemberBinding      .      b
               |      \
               .       a
      
           The advantage of using regular syntax nodes on the right side is that semantical analysis “just works”.  Naturally, because of the topology, the API cannot ask nonsensical questions like - what is the type of subexpression “R?.a.b” ?
           Since “R?.a.b” is not a subexpression, there is no way to ask such question.
           It is however possible to interrogate member accesses – they are just regular member accesses (in both syntax and bound trees) so they naturally know their types etc…
      
           == Binding
      
           Binding of the tree above is fairly simple – I only had to add binding support for the left-lowermost binding nodes. And what comes out is really just regular access expressions with placeholder receiver.
           I cannot refer to the actual receiver since we are not evaluating it again.
      
           In terms of schema - Bound tree actually needed even fewer changes than syntax tree – the bound tree for the above expression is just a regular bound tree. It is isomorphic to the syntax.
           The only new bound nodes are the root BoundConditionalAccess and the left-lowermost placeholder receiver – BoundConditionalReceiver.
      
               BoundConditionalAccess
                /                  \
           <BoundExpr>         BoundMemberAccess {c}
                                    /
                              BoundCall {b}
                             /          \
            BoundMemberAccess {a}        List<Args>{ x }
                          /
           BoundConditionalReceiver
      
           == Dataflow
      
           Dataflow considers BoundConditionalReceiver always assigned. However the whole WhenNotNull is reachable conditionally  - i.e. assignedVariables state is forked when going into WhenNotNull.
           “receiver is a const” situation is handled trivially. That is similar to the ?? operator but somewhat inverted.
      
           == Emit
      
           There are two ways to emit this :
           - In complex cases (nullables, async, expr trees) we lower the conditional access into a ternary with consequence being rewritten as0is with just BoundConditionalReceiver replaced by a temp for the receiver value.
           - In simple case (all reference types), we do not lower the node, emit of BoundConditionalAccess dups the receiver (thus avoiding an IL temp) , checks it for null and conditionally executes the the access expression.
           BoundConditionalReceiver is handled by emit by not emitting anything since it represents receiver value and that is on the stack already.
       (changeset 1249636)
      6f2e0b6d
  3. 05 5月, 2014 1 次提交
  4. 04 5月, 2014 1 次提交
  5. 03 5月, 2014 10 次提交
    • A
      Migrated state of “Primary Constructors” implementation equivalent to... · a08b5fb9
      AlekseyTs 提交于
      Migrated state of “Primary Constructors” implementation equivalent to https://roslyn.codeplex.com/SourceControl/changeset/af3db25146a74523fbb2cf11ef00ddec6c0c3690. (changeset 1249690)
      a08b5fb9
    • T
      In C# lowering of async method stored the state machine type on... · 073242b0
      TomasMatousek 提交于
      In C# lowering of async method stored the state machine type on SourceMethodSymbol so it can later be used when emitting synthesized attributes of the method. This may cause issues when emitting the same compilation twice with different options that affect the state machine type.
           Instead we should store the state machine type to the current PEModuleBuilder. Rather then actually storing it there and adding a dependency on PEModuleBuilder to the attribute generation this change introduces ModuleCompilationState (similar to TypeCompilationState) and threads that one.
           This type is designed to be mutable during compilation (lowering) and immutable during emit. The idea is that all data currently stored in PEModuleBuilder that are produced during compilation and only read in emit could be moved there. Only emit specific data would remain on PEModuleBuilder.
      
           Also refactors Compilation.Compile to remove some duplication and make it cleaner.
       (changeset 1249664)
      073242b0
    • V
      Implementation of conditional access operators - ?. and ?[] · 3911d7a2
      VSadov 提交于
       Change Description:
      
           Implementation of conditional access operators ( ?. and ?[] )
      
           The grammar roughly looks like:
      
           expr ::= | ...
                    | expr ? tail
      
           tail ::= | tailopt . id
           tail ::= | tailopt .$ id                        <---   this is NYI in this change
                    | tailopt [ expr-args ]
                    | tail ( expr-args )
      
           Note that the tail isn’t optional for invocation: there is no ?(…) operator.
      
           Interesting implementation points:
      
           == Parsing/syntax
      
           Syntax tree is right associative – it has the same topology as in the grammar. However I did not create special variants for all the kinds of syntax that could be produced by the parsing of the tail of accessors.
           I just use regular syntax nodes with exception of the topmost node that is the conditional access operator itself and the lower-leftmost node that textually starts the accessor tail.
      
           The root node looks like –
      
           ConditionalAccessExpression
           {
              ExpressionSyntax Expression;
              SyntaxToken OperatorToken;                  // always “?”
              ExpressionSyntax WhenNotNull;              // by analogy with conditional expression which uses WhenTrue
           }
      
           WhenNotNull is an ExpressionSyntax that represent the sequence of postfix operations conditionally applied to the Expression. These are regular InvocationExpressions, MemberAccesses, ElementAcesses – whatever postfix operators we have.
      
           The only special part about WhenNotNull is that the low-leftmost expression child is one of 2 special “binding” nodes – MemberBindingExpression, ElementBindingExpression.
      
           Binding expressions are entities which can start the chain of WhenNotNull . Textually they look like  -  “ .SimpleName“ ,  “[argList]” or “$Name” (when $ accessor is supported).
           Note that there is no InvocationBinding, since we do not allow () to start the chain of applications – you cannot do “a?(arg)”.
           The binding expression syntaxes are basically versions of corresponding member/element/dollar access expressions without receivers.
      
           R?.a.b(x).c
      
           Would parse as
      
               ConditionalAccess
             /         |         \
           R           ?          MemberAccess
                                       /    |   \
                             Invocation     .     c
                            /           \
                      MemberAccess       ArgList{( x )}
                     /        |    \
           MemberBinding      .      b
               |      \
               .       a
      
           The advantage of using regular syntax nodes on the right side is that semantical analysis “just works”.  Naturally, because of the topology, the API cannot ask nonsensical questions like - what is the type of subexpression “R?.a.b” ?
           Since “R?.a.b” is not a subexpression, there is no way to ask such question.
           It is however possible to interrogate member accesses – they are just regular member accesses (in both syntax and bound trees) so they naturally know their types etc…
      
           == Binding
      
           Binding of the tree above is fairly simple – I only had to add binding support for the left-lowermost binding nodes. And what comes out is really just regular access expressions with placeholder receiver.
           I cannot refer to the actual receiver since we are not evaluating it again.
      
           In terms of schema - Bound tree actually needed even fewer changes than syntax tree – the bound tree for the above expression is just a regular bound tree. It is isomorphic to the syntax.
           The only new bound nodes are the root BoundConditionalAccess and the left-lowermost placeholder receiver – BoundConditionalReceiver.
      
               BoundConditionalAccess
                /                  \
           <BoundExpr>         BoundMemberAccess {c}
                                    /
                              BoundCall {b}
                             /          \
            BoundMemberAccess {a}        List<Args>{ x }
                          /
           BoundConditionalReceiver
      
           == Dataflow
      
           Dataflow considers BoundConditionalReceiver always assigned. However the whole WhenNotNull is reachable conditionally  - i.e. assignedVariables state is forked when going into WhenNotNull.
           “receiver is a const” situation is handled trivially. That is similar to the ?? operator but somewhat inverted.
      
           == Emit
      
           There are two ways to emit this :
           - In complex cases (nullables, async, expr trees) we lower the conditional access into a ternary with consequence being rewritten as0is with just BoundConditionalReceiver replaced by a temp for the receiver value.
           - In simple case (all reference types), we do not lower the node, emit of BoundConditionalAccess dups the receiver (thus avoiding an IL temp) , checks it for null and conditionally executes the the access expression.
           BoundConditionalReceiver is handled by emit by not emitting anything since it represents receiver value and that is on the stack already.
       (changeset 1249636)
      3911d7a2
    • C
      EnC: MethodImpl entries should only be added if the implementing method was... · 093f8990
      ChuckStoner 提交于
      EnC: MethodImpl entries should only be added if the implementing method was added (changeset 1249535)
      093f8990
    • K
    • M
      db06992e
    • Y
      Bug fix (687246, 687 373): globalization - pass proper culture information... · de3df47e
      YingP99 提交于
      Bug fix (687246, 687 373): globalization - pass proper culture information when calling some TryParse() and IndexOf() methods (changeset 1249342)
      de3df47e
    • A
      Fixet typo in a comment. (changeset 1249258) · 30f088ca
      AlekseyTs 提交于
      30f088ca
    • A
      daa115ac
    • K
      Perf: use Type instead of string as dictionary key. · 225fcf1e
      kayleh 提交于
      This avoids unnecessary calls to AssemblyQualifiedName. (changeset 1248550)
      225fcf1e
  6. 02 5月, 2014 6 次提交
  7. 01 5月, 2014 3 次提交
    • T
      We need to be more conscious about producing synthesized symbols during... · 211b47ed
      TomasMatousek 提交于
      We need to be more conscious about producing synthesized symbols during lowering in order to enable EnC of method bodies whose lowering produce such symbols (e.g. lambdas, iterators, dynamic sites, etc.).
      
           This change refactors synthesized symbols in C# so that all symbols produced during lowering phase implement an interface (ISynthesizedMethodBodyImplementationSymbol) that can be used in the emit phase to retrieve information necessary for updating the corresponding metadata entities should they enter EnC.
      
           I also attempted to somewhat improve and increase consistency of the naming of synthesized symbols involved in this change.
      
           No new functionality is added by this change. (changeset 1247789)
      211b47ed
    • A
      DevDiv #924473: Inherited interface members in crefs · ac4666fe
      acasey 提交于
      Crefs ignore inherited members, but I missed a few cases.
      
      1) Binder lookup dropped them, but semantic model lookup (totally separate code path) did not.
      2) Base interface members were dropped, but System.Object members were not (except with recovery code during binding). (changeset 1245954)
      ac4666fe
    • C
  8. 30 4月, 2014 2 次提交
  9. 29 4月, 2014 1 次提交
  10. 28 4月, 2014 2 次提交
    • K
      This fixes #90 (https://roslyn.codeplex.com/workitem/90). · 36e6576a
      Kevin_H 提交于
      There were issues with the PE headers generated by the compiler when emitting assemblies with no win32 resources (default behavior when you call Compilation.Emit).
      
      If the size of a section is zero, then the relative virtual address should also be zero.  Previously, we would unconditionally set the address of the resource section to the end of the most recently preceding section that contained any data.  This was wrong in and of itself, but it also had the knock-on effect of breaking the logic in PeWriter.WriteRelocSection that is supposed to pad the last section to align with the file alignment boundary. (changeset 1240642)
      36e6576a
    • S
      WarnAsError shouldn't turn info\hidden diagnostics into errors · d5ad581f
      srivatsn 提交于
      When warnaserror is set for a project, we set the GeneralDiagnosticOption on CompilationOptions to be error and that turns any diagnostic that doesn't have a specific option set to an error. This means diagnostcs from simplify typename etc. get turned into errors and squiggles everything. The consensus from the diagnostic team meeting was this:
      * When doing warn-as-error, don't raise severity for anything *below* warning (info or hidden).
      * When doing suppress-all-warnings, don't lower severity for anything *above* warning (error).
      
      Implementing this in C# and VB. Tests will follow.
       (changeset 1239863)
      d5ad581f