예제 #1
0
 protected override void OnTranslate(ShaderTranslationContext sc, IdentifierNameSyntax syntax, ScopeInfo scope)
 {
     if (syntax.Parent is InvocationExpressionSyntax invSyntax)
     {
         string translatedIntrinsic = ShaderType.GetIntrinsicTranslation(sc, syntax.Identifier.ValueText);
         sc.Source.Append(translatedIntrinsic);
     }
     else
     {
         ScopeInfo    cScope = scope.FindOfType(ScopeType.Class);
         PropertyInfo pInfo  = cScope?.TypeInfo.OriginalType.GetProperty(syntax.Identifier.ValueText);
         if (pInfo != null)
         {
             if (syntax.Parent is AssignmentExpressionSyntax aSyntax)
             {
                 if (aSyntax.Left == syntax)
                 {
                     TranslatePropertyAssignment(sc, syntax, aSyntax);
                 }
             }
             else if (syntax.Parent is MemberAccessExpressionSyntax mSyntax &&
                      mSyntax.Parent is AssignmentExpressionSyntax maSyntax &&
                      maSyntax.Left == mSyntax)
             {
                 TranslatePropertyAssignment(sc, syntax, maSyntax);
             }
             else // Safe to assume it's a property get call.
             {
                 sc.Source.Append($"get{syntax.Identifier}()");
             }
         }
        protected override void OnTranslate(ShaderTranslationContext sc, MemberAccessExpressionSyntax syntax, ScopeInfo scope)
        {
            switch (syntax.Expression)
            {
            case IdentifierNameSyntax idSyntax:
                // Is this a static class identifier?
                // Static classes are abstract and sealed at IL level.
                Type targetType = ShaderType.Resolve(sc, idSyntax.Identifier.ValueText);
                if (targetType != null && targetType.IsClass && targetType.IsAbstract && targetType.IsSealed)
                {
                    // Is the member a constant value? If so, we can take it's value directly.
                    FieldInfo fInfo = targetType.GetField(syntax.Name.Identifier.ValueText);
                    if (fInfo != null && (fInfo.Attributes & FieldAttributes.Literal) == FieldAttributes.Literal)
                    {
                        object val = fInfo.GetValue(null);
                        if (val != null)
                        {
                            sc.Source.Append(val.ToString());
                            sc.CompleteChildren(syntax);
                            return;
                        }
                    }
                }
                else
                {
                    ScopeInfo cScope = scope.FindOfType(ScopeType.Class);
                    if (cScope == sc.Source.RootScope)
                    {
                        FieldInfo fInfo = cScope.TypeInfo.OriginalType.GetField(idSyntax.Identifier.ValueText);
                        if (fInfo != null && sc.ConstantBuffers.Values.Any(x => x.TypeInfo == fInfo.FieldType))
                        {
                            if (!sc.Language.InstancedConstantBuffers)
                            {
                                sc.CompleteSelfAndChildren(syntax.Expression);
                                sc.Runner.Translate(sc, syntax.Name);
                                return;
                            }
                        }
                    }
                }
                break;

            case ThisExpressionSyntax thisSyntax:
            case BaseExpressionSyntax baseSyntax:
                ScopeInfo pScope = scope.FindOfType(ScopeType.Class);
                if (pScope.TypeInfo.OriginalType == sc.ShaderType)
                {
                    sc.Complete(syntax.Expression);

                    // Are we translating a shader intrinsic method/function?
                    if (syntax.Name is IdentifierNameSyntax idSyntax && syntax.Parent is InvocationExpressionSyntax)
                    {
                        string translatedIntrinsic = ShaderType.GetIntrinsicTranslation(sc, idSyntax.Identifier.ValueText);
                        sc.Source.Append(translatedIntrinsic);
                        sc.Complete(syntax.Name);
                    }
                    return;
                }
                break;
            }

            sc.Runner.Translate(sc, syntax.Expression);
            sc.Source.Append(syntax.OperatorToken);
            sc.Runner.Translate(sc, syntax.Name);
        }