public static ScopeAccessInformation AddStructureExitPoints(
            this ScopeAccessInformation scopeInformation,
            CSharpName structureExitFlagNameIfAny,
            ScopeAccessInformation.ExitableNonScopeDefiningConstructOptions structureExitType)
        {
            if (scopeInformation == null)
            {
                throw new ArgumentNullException("scopeInformation");
            }
            if (!Enum.IsDefined(typeof(ScopeAccessInformation.ExitableNonScopeDefiningConstructOptions), structureExitType))
            {
                throw new ArgumentOutOfRangeException("structureExitType");
            }

            return(new ScopeAccessInformation(
                       scopeInformation.Parent,
                       scopeInformation.ScopeDefiningParent,
                       scopeInformation.ParentReturnValueNameIfAny,
                       scopeInformation.ErrorRegistrationTokenIfAny,
                       scopeInformation.DirectedWithReferenceIfAny,
                       scopeInformation.ExternalDependencies,
                       scopeInformation.Classes,
                       scopeInformation.Functions,
                       scopeInformation.Properties,
                       scopeInformation.Constants,
                       scopeInformation.Variables,
                       scopeInformation.StructureExitPoints
                       .Add(new ScopeAccessInformation.ExitableNonScopeDefiningConstructDetails(
                                structureExitFlagNameIfAny,
                                structureExitType
                                ))
                       ));
        }
Ejemplo n.º 2
0
        public ForEachBlockTranslator(
            CSharpName supportRefName,
            CSharpName envClassName,
            CSharpName envRefName,
            CSharpName outerClassName,
            CSharpName outerRefName,
            VBScriptNameRewriter nameRewriter,
            TempValueNameGenerator tempNameGenerator,
            ITranslateIndividualStatements statementTranslator,
            ITranslateValueSettingsStatements valueSettingStatementTranslator,
            ILogInformation logger)
            : base(supportRefName, envClassName, envRefName, outerClassName, outerRefName, nameRewriter, tempNameGenerator, statementTranslator, valueSettingStatementTranslator, logger)
        {
            if (statementTranslator == null)
            {
                throw new ArgumentNullException("statementTranslator");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            _statementTranslator = statementTranslator;
            _logger = logger;
        }
        public OuterScopeBlockTranslator(
            CSharpName startNamespace,
            CSharpName startClassName,
            CSharpName startMethodName,
            CSharpName runtimeDateLiteralValidatorClassName,
            CSharpName supportRefName,
            CSharpName envClassName,
            CSharpName envRefName,
            CSharpName outerClassName,
            CSharpName outerRefName,
            VBScriptNameRewriter nameRewriter,
            TempValueNameGenerator tempNameGenerator,
            ITranslateIndividualStatements statementTranslator,
            ITranslateValueSettingsStatements valueSettingStatementTranslator,
            NonNullImmutableList <NameToken> externalDependencies,
            OutputTypeOptions outputType,
            ILogInformation logger)
            : base(supportRefName, envClassName, envRefName, outerClassName, outerRefName, nameRewriter, tempNameGenerator, statementTranslator, valueSettingStatementTranslator, logger)
        {
            if (startNamespace == null)
            {
                throw new ArgumentNullException("startNamespace");
            }
            if (startClassName == null)
            {
                throw new ArgumentNullException("startClassName");
            }
            if (startMethodName == null)
            {
                throw new ArgumentNullException("startMethodName");
            }
            if (runtimeDateLiteralValidatorClassName == null)
            {
                throw new ArgumentNullException("runtimeDateLiteralValidatorClassName");
            }
            if (externalDependencies == null)
            {
                throw new ArgumentNullException("externalDependencies");
            }
            if (!Enum.IsDefined(typeof(OutputTypeOptions), outputType))
            {
                throw new ArgumentOutOfRangeException("outputType");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            _startNamespace  = startNamespace;
            _startClassName  = startClassName;
            _startMethodName = startMethodName;
            _runtimeDateLiteralValidatorClassName = runtimeDateLiteralValidatorClassName;
            _externalDependencies = externalDependencies;
            _outputType           = outputType;
            _logger = logger;
        }
Ejemplo n.º 4
0
 public ClassBlockTranslator(
     CSharpName supportRefName,
     CSharpName envClassName,
     CSharpName envRefName,
     CSharpName outerClassName,
     CSharpName outerRefName,
     VBScriptNameRewriter nameRewriter,
     TempValueNameGenerator tempNameGenerator,
     ITranslateIndividualStatements statementTranslator,
     ITranslateValueSettingsStatements valueSettingStatementTranslator,
     ILogInformation logger)
     : base(supportRefName, envClassName, envRefName, outerClassName, outerRefName, nameRewriter, tempNameGenerator, statementTranslator, valueSettingStatementTranslator, logger)
 {
 }
        public FuncByRefMapping(NameToken from, CSharpName to, bool mappedValueIsReadOnly)
        {
            if (from == null)
            {
                throw new ArgumentNullException("from");
            }
            if (to == null)
            {
                throw new ArgumentNullException("to");
            }

            From = from;
            To   = to;
            MappedValueIsReadOnly = mappedValueIsReadOnly;
        }
Ejemplo n.º 6
0
        public ValueSettingStatementsTranslator(
            CSharpName supportRefName,
            CSharpName envRefName,
            CSharpName outerRefName,
            VBScriptNameRewriter nameRewriter,
            ITranslateIndividualStatements statementTranslator,
            ILogInformation logger)
        {
            if (supportRefName == null)
            {
                throw new ArgumentNullException("supportRefName");
            }
            if (envRefName == null)
            {
                throw new ArgumentNullException("envRefName");
            }
            if (outerRefName == null)
            {
                throw new ArgumentNullException("outerRefName");
            }
            if (nameRewriter == null)
            {
                throw new ArgumentNullException("nameRewriter");
            }
            if (statementTranslator == null)
            {
                throw new ArgumentNullException("statementTranslator");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            _supportRefName      = supportRefName;
            _envRefName          = envRefName;
            _outerRefName        = outerRefName;
            _nameRewriter        = nameRewriter;
            _statementTranslator = statementTranslator;
            _logger = logger;
        }
Ejemplo n.º 7
0
        private TranslationResult Translate(
            NonNullImmutableList <ICodeBlock> blocks,
            ScopeAccessInformation scopeAccessInformation,
            bool supportsExit,
            CSharpName earlyExitNameIfAny,
            int indentationDepth)
        {
            if (blocks == null)
            {
                throw new ArgumentNullException("block");
            }
            if (scopeAccessInformation == null)
            {
                throw new ArgumentNullException("scopeAccessInformation");
            }
            if (!supportsExit && (earlyExitNameIfAny != null))
            {
                throw new ArgumentException("earlyExitNameIfAny should always be null if supportsExit is false");
            }
            if (indentationDepth < 0)
            {
                throw new ArgumentOutOfRangeException("indentationDepth", "must be zero or greater");
            }

            // Add a StructureExitPoint entry for the current loop so that the "early-exit" logic described in the Translate method above is possible
            if (supportsExit)
            {
                scopeAccessInformation = scopeAccessInformation.AddStructureExitPoints(
                    earlyExitNameIfAny,
                    ScopeAccessInformation.ExitableNonScopeDefiningConstructOptions.Do
                    );
            }
            return(base.TranslateCommon(
                       base.GetWithinFunctionBlockTranslators(),
                       blocks,
                       scopeAccessInformation,
                       indentationDepth
                       ));
        }
        /// <summary>
        /// If the parent is scope-defining then both the parent and scopeDefiningParent references will be set to it, this is a convenience method to
        /// save having to specify it explicitly for both
        /// </summary>
        public static ScopeAccessInformation Extend(
            this ScopeAccessInformation scopeInformation,
            IDefineScope parent,
            CSharpName parentReturnValueNameIfAny,
            CSharpName errorRegistrationTokenIfAny,
            NonNullImmutableList <ICodeBlock> blocks)
        {
            if (scopeInformation == null)
            {
                throw new ArgumentNullException("scopeInformation");
            }
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }
            if (blocks == null)
            {
                throw new ArgumentNullException("blocks");
            }

            return(Extend(scopeInformation, parent, parent, parentReturnValueNameIfAny, errorRegistrationTokenIfAny, blocks));
        }
        private IEnumerable <TranslatedStatement> TranslateFunctionHeader(AbstractFunctionBlock functionBlock, ScopeAccessInformation scopeAccessInformation, CSharpName returnValueNameIfAny, int indentationDepth)
        {
            if (functionBlock == null)
            {
                throw new ArgumentNullException("functionBlock");
            }
            if (functionBlock.HasReturnValue && (returnValueNameIfAny == null))
            {
                throw new ArgumentException("returnValueNameIfAny must not be null if functionBlock.HasReturnValue is true");
            }
            if (scopeAccessInformation == null)
            {
                throw new ArgumentNullException("scopeAccessInformation");
            }
            if (indentationDepth < 0)
            {
                throw new ArgumentOutOfRangeException("indentationDepth", "must be zero or greater");
            }

            var content = new StringBuilder();

            content.Append(functionBlock.IsPublic ? "public" : "private");
            content.Append(" ");
            content.Append(functionBlock.HasReturnValue ? "object" : "void");
            content.Append(" ");
            content.Append(_nameRewriter.GetMemberAccessTokenName(functionBlock.Name));
            content.Append("(");
            var numberOfParameters = functionBlock.Parameters.Count();

            for (var index = 0; index < numberOfParameters; index++)
            {
                var parameter = functionBlock.Parameters.ElementAt(index);
                if (parameter.ByRef)
                {
                    content.Append("ref ");
                }
                content.Append("object ");
                content.Append(_nameRewriter.GetMemberAccessTokenName(parameter.Name));
                if (index < (numberOfParameters - 1))
                {
                    content.Append(", ");
                }
            }
            content.Append(")");

            var translatedStatements = new List <TranslatedStatement>();

            if (functionBlock.IsDefault)
            {
                translatedStatements.Add(new TranslatedStatement("[" + typeof(IsDefault).FullName + "]", indentationDepth, functionBlock.Name.LineIndex));
            }
            var property = functionBlock as PropertyBlock;

            if (property != null)
            {
                // All property blocks that are translated into C# methods needs to be decorated with the [TranslatedProperty] attribute. The [TranslatedProperty] attribute
                // was originally intended only for indexed properties (which C# can only support one of per class but VBScript classes can have as many as they like) but
                // a class with an indexed property will be emitted to inherit from TranslatedPropertyIReflectImplementation, which will try to identify properties based
                // upon the presence of [TranslatedProperty] attributes - if some (ie. indexed properties) have these and others (non-indexed properties) don't then it
                // will result in runtime failures. So we could apply the attribute to indexed properties and all properties within classes that have at least one
                // indexed property but that feels like complications for little benefit so I think it's easier to just put it on ALL from-property methods.
                translatedStatements.Add(
                    new TranslatedStatement(
                        string.Format(
                            "[TranslatedProperty({0})]",                             // Note: Safe to assume that using statements are present for the namespace that contains TranslatedProperty
                            property.Name.Content.ToLiteral()
                            ),
                        indentationDepth,
                        functionBlock.Name.LineIndex
                        )
                    );
            }
            translatedStatements.Add(new TranslatedStatement(content.ToString(), indentationDepth, functionBlock.Name.LineIndex));
            translatedStatements.Add(new TranslatedStatement("{", indentationDepth, functionBlock.Name.LineIndex));
            if (functionBlock.HasReturnValue && functionBlock.Statements.Any() && !IsSingleReturnValueStatementFunctionWithoutAnyByRefMappings(functionBlock, scopeAccessInformation))
            {
                translatedStatements.Add(new TranslatedStatement(
                                             base.TranslateVariableInitialisation(
                                                 new VariableDeclaration(
                                                     new DoNotRenameNameToken(
                                                         returnValueNameIfAny.Name,
                                                         functionBlock.Name.LineIndex
                                                         ),
                                                     VariableDeclarationScopeOptions.Private,
                                                     null    // Not declared as an array
                                                     ),
                                                 ScopeLocationOptions.WithinFunctionOrPropertyOrWith
                                                 ),
                                             indentationDepth + 1,
                                             functionBlock.Name.LineIndex
                                             ));
            }
            return(translatedStatements);
        }
        public static ScopeAccessInformation Extend(
            this ScopeAccessInformation scopeInformation,
            IHaveNestedContent parent,
            IDefineScope scopeDefiningParent,
            CSharpName parentReturnValueNameIfAny,
            CSharpName errorRegistrationTokenIfAny,
            NonNullImmutableList <ICodeBlock> blocks)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }
            if (scopeDefiningParent == null)
            {
                throw new ArgumentNullException("scopeDefiningParent");
            }
            if (scopeInformation == null)
            {
                throw new ArgumentNullException("scopeInformation");
            }
            if (blocks == null)
            {
                throw new ArgumentNullException("blocks");
            }

            var blocksScopeLocation = scopeDefiningParent.Scope;

            blocks = FlattenAllAccessibleBlockLevelCodeBlocks(blocks);
            var variables = scopeInformation.Variables.AddRange(
                blocks
                .OfType <DimStatement>()    // This covers DIM, REDIM, PRIVATE and PUBLIC (they may all be considered the same for these purposes)
                .SelectMany(d => d.Variables.Select(v => new ScopedNameToken(
                                                        v.Name.Content,
                                                        v.Name.LineIndex,
                                                        blocksScopeLocation
                                                        )))
                );

            if (scopeDefiningParent != null)
            {
                variables = variables.AddRange(
                    scopeDefiningParent.ExplicitScopeAdditions
                    .Select(v => new ScopedNameToken(
                                v.Content,
                                v.LineIndex,
                                blocksScopeLocation
                                )
                            )
                    );
            }
            var constants = scopeInformation.Constants.AddRange(
                blocks
                .OfType <ConstStatement>()
                .SelectMany(c => c.Values.Select(v => new ScopedNameToken(
                                                     v.Name.Content,
                                                     v.Name.LineIndex,
                                                     blocksScopeLocation
                                                     )))
                );

            return(new ScopeAccessInformation(
                       parent,
                       scopeDefiningParent,
                       parentReturnValueNameIfAny,
                       errorRegistrationTokenIfAny,
                       scopeInformation.DirectedWithReferenceIfAny,
                       scopeInformation.ExternalDependencies,
                       scopeInformation.Classes.AddRange(
                           blocks
                           .Where(b => b is ClassBlock)
                           .Cast <ClassBlock>()
                           .Select(c => new ScopedNameToken(c.Name.Content, c.Name.LineIndex, ScopeLocationOptions.OutermostScope)) // These are always OutermostScope
                           ),
                       scopeInformation.Functions.AddRange(
                           blocks
                           .Where(b => (b is FunctionBlock) || (b is SubBlock))
                           .Cast <AbstractFunctionBlock>()
                           .Select(b => new ScopedNameToken(b.Name.Content, b.Name.LineIndex, blocksScopeLocation))
                           ),
                       scopeInformation.Properties.AddRange(
                           blocks
                           .Where(b => b is PropertyBlock)
                           .Cast <PropertyBlock>()
                           .Select(p => new ScopedNameToken(p.Name.Content, p.Name.LineIndex, ScopeLocationOptions.WithinClass)) // These are always WithinClass
                           ),
                       constants,
                       variables,
                       scopeInformation.StructureExitPoints
                       ));
        }
        /// <summary>
        /// This Translate signature is what the others call into - it doesn't try to hide the fact that externalDependencies should be a NonNullImmutableList
        /// of strings and it requires an ILogInformation implementation to deal with logging warnings
        /// </summary>
        public static NonNullImmutableList <TranslatedStatement> Translate(
            string scriptContent,
            NonNullImmutableList <string> externalDependencies,
            OuterScopeBlockTranslator.OutputTypeOptions outputType,
            ILogInformation logger)
        {
            if (scriptContent == null)
            {
                throw new ArgumentNullException("scriptContent");
            }
            if (externalDependencies == null)
            {
                throw new ArgumentNullException("externalDependencies");
            }
            if ((outputType != OuterScopeBlockTranslator.OutputTypeOptions.Executable) && (outputType != OuterScopeBlockTranslator.OutputTypeOptions.WithoutScaffolding))
            {
                throw new ArgumentOutOfRangeException("outputType");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            var startNamespace  = new CSharpName("TranslatedProgram");
            var startClassName  = new CSharpName("Runner");
            var startMethodName = new CSharpName("Go");
            var runtimeDateLiteralValidatorClassName = new CSharpName("RuntimeDateLiteralValidator");
            var supportRefName = new CSharpName("_");
            var envClassName   = new CSharpName("EnvironmentReferences");
            var envRefName     = new CSharpName("_env");
            var outerClassName = new CSharpName("GlobalReferences");
            var outerRefName   = new CSharpName("_outer");
            VBScriptNameRewriter nameRewriter        = name => new CSharpName(DefaultRuntimeSupportClassFactory.DefaultNameRewriter(name.Content));
            var tempNameGeneratorNextNumber          = 0;
            TempValueNameGenerator tempNameGenerator = (optionalPrefix, scopeAccessInformation) =>
            {
                // To get unique names for any given translation, a running counter is maintained and appended to the end of the generated
                // name. This is only run during translation (this code is not used during execution) so there will be a finite number of
                // times that this is called (so there should be no need to worry about the int value overflowing!)
                return(new CSharpName(((optionalPrefix == null) ? "temp" : optionalPrefix.Name) + (++tempNameGeneratorNextNumber).ToString()));
            };
            var statementTranslator = new StatementTranslator(supportRefName, envRefName, outerRefName, nameRewriter, tempNameGenerator, logger);
            var codeBlockTranslator = new OuterScopeBlockTranslator(
                startNamespace,
                startClassName,
                startMethodName,
                runtimeDateLiteralValidatorClassName,
                supportRefName,
                envClassName,
                envRefName,
                outerClassName,
                outerRefName,
                nameRewriter,
                tempNameGenerator,
                statementTranslator,
                new ValueSettingStatementsTranslator(supportRefName, envRefName, outerRefName, nameRewriter, statementTranslator, logger),
                externalDependencies.Select(name => new NameToken(name, 0)).ToNonNullImmutableList(),
                outputType,
                logger
                );

            return(codeBlockTranslator.Translate(
                       Parse(scriptContent).ToNonNullImmutableList()
                       ));
        }
Ejemplo n.º 12
0
        public static ScopeAccessInformation SetErrorRegistrationToken(this ScopeAccessInformation scopeAccessInformation, CSharpName errorRegistrationTokenIfAny)
        {
            if (scopeAccessInformation == null)
            {
                throw new ArgumentNullException("scopeAccessInformation");
            }

            return(new ScopeAccessInformation(
                       scopeAccessInformation.Parent,
                       scopeAccessInformation.ScopeDefiningParent,
                       scopeAccessInformation.ParentReturnValueNameIfAny,
                       errorRegistrationTokenIfAny,
                       scopeAccessInformation.DirectedWithReferenceIfAny,
                       scopeAccessInformation.ExternalDependencies,
                       scopeAccessInformation.Classes,
                       scopeAccessInformation.Functions,
                       scopeAccessInformation.Properties,
                       scopeAccessInformation.Constants,
                       scopeAccessInformation.Variables,
                       scopeAccessInformation.StructureExitPoints
                       ));
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Get the name of the containing reference where applicable. For outermost scope variable references, the target container will be the reference to the
        /// outer most scope (aka. Global References) instance. For undeclared variables, it will be the Environment References instance when in the outermost scope
        /// but undeclared variables within functions or properties are implicitly declared within that function or property, and so need no target container to be
        /// specified. This will return null if no container is required to locate the specified target.
        /// </summary>
        public static CSharpName GetNameOfTargetContainerIfAnyRequired(
            this ScopeAccessInformation scopeAccessInformation,
            NameToken target,
            CSharpName envRefName,
            CSharpName outerRefName,
            VBScriptNameRewriter nameRewriter)
        {
            if (scopeAccessInformation == null)
            {
                throw new ArgumentNullException("scopeAccessInformation");
            }
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (envRefName == null)
            {
                throw new ArgumentNullException("envRefName");
            }
            if (outerRefName == null)
            {
                throw new ArgumentNullException("outerRefName");
            }
            if (nameRewriter == null)
            {
                throw new ArgumentNullException("nameRewriter");
            }

            // TargetCurrentClassToken indicates a "Me" reference, which never requires a target container - it is always valid where it is (even in the
            // outermost scope, VBScript doesn't require that "Me" be used only within a VBScript class)
            if (target is TargetCurrentClassToken)
            {
                return(null);
            }

            // Similarly, if the target is a NameToken that comes from content that was partially processed and then rewritten then we can assume that
            // it does not need any target-container logic re-applying
            if (target is ProcessedNameToken)
            {
                return(null);
            }

            var rewrittenTargetName = nameRewriter(target).Name;
            var targetReferenceDetailsIfAvailable = scopeAccessInformation.TryToGetDeclaredReferenceDetails(target, nameRewriter);

            if (targetReferenceDetailsIfAvailable == null)
            {
                if (scopeAccessInformation.ScopeDefiningParent.Scope == ScopeLocationOptions.WithinFunctionOrPropertyOrWith)
                {
                    // If an undeclared variable is accessed within a function (or property) then it is treated as if it was declared to be restricted
                    // to the current scope, so the nameOfTargetContainerIfRequired should be null in this case (this means that the UndeclaredVariables
                    // data returned from this process should be translated into locally-scoped DIM statements at the top of the function / property).
                    return(null);
                }
                return(envRefName);
            }
            else if (targetReferenceDetailsIfAvailable.ReferenceType == ReferenceTypeOptions.ExternalDependency)
            {
                return(envRefName);
            }
            else if (targetReferenceDetailsIfAvailable.ScopeLocation == ScopeLocationOptions.OutermostScope)
            {
                // 2014-01-06 DWR: Used to only apply this logic if the target reference was in the OutermostScope and we were currently inside a
                // class but I'm restructuring the outer scope so that declared variables and functions are inside a class that the outermost scope
                // references in an identical manner to the class functions (and properties) so the outerRefName should used every time that an
                // OutermostScope reference is accessed
                return(outerRefName);
            }
            return(null);
        }