public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
        {

            object item = this.ClassAction(typeDefinitionAst.Name, typeDefinitionAst.Extent, this.GetCurrentNestingLevel(), this.GetCurrentParentObject());
            foreach (MemberAst member in typeDefinitionAst.Members)
            {
                if (member is PropertyMemberAst)
                {
                   this.ClassPropertyAction(member.Name, member.Extent, this.GetCurrentNestingLevel() + 1, item);
                } 
                else if (member is FunctionMemberAst)
                {
                    FunctionMemberAst functionMember = (FunctionMemberAst)member;
                    object newParentObject;
                    if (functionMember.IsConstructor)
                    {
                        newParentObject = this.ClassConstructorAction(member.Name, member.Extent, this.GetCurrentNestingLevel() + 1, item);                        
                    }
                    else
                    {
                        newParentObject = this.ClassMethodAction(member.Name, member.Extent, this.GetCurrentNestingLevel() + 1, item);
                    }
                    this.VisitChildren(functionMember.Body, newParentObject);
                }
            }
            return AstVisitAction.SkipChildren;
        }
示例#2
0
        /// <summary>
        /// Return the most deep typeDefinitionAst in the current context.
        /// </summary>
        /// <returns>TypeDefinitionAst or null, if currently not in type definition.</returns>
        public TypeDefinitionAst GetCurrentTypeDefinitionAst()
        {
            for (int i = _scopes.Count - 1; i >= 0; i--)
            {
                TypeDefinitionAst ast = _scopes[i]._ast as TypeDefinitionAst;
                if (ast != null)
                {
                    return(ast);
                }
            }

            return(null);
        }
示例#3
0
 internal void AddType(Parser parser, TypeDefinitionAst typeDefinitionAst)
 {
     TypeLookupResult result;
     if (_typeTable.TryGetValue(typeDefinitionAst.Name, out result))
     {
         if (result.ExternalNamespaces != null)
         {
             // override external type by the type defined in the current namespace
             result.ExternalNamespaces = null;
             result.Type = typeDefinitionAst;
         }
         else
         {
             parser.ReportError(typeDefinitionAst.Extent, () => ParserStrings.MemberAlreadyDefined, typeDefinitionAst.Name);
         }
     }
     else
     {
         _typeTable.Add(typeDefinitionAst.Name, new TypeLookupResult(typeDefinitionAst));
     }
 }
示例#4
0
        /// <summary>
        /// Convert the cacheItem to a PSClassInfo object.
        /// For this, we call Get-Module -List with module name.
        /// </summary>
        /// <param name="classNameMatcher">Wildcard pattern matcher for comparing class name.</param>
        /// <param name="modulePath">Path to the module where the class is defined.</param>
        /// <returns>Converted PSClassInfo object.</returns>
        private PSClassInfo CachedItemToPSClassInfo(WildcardPattern classNameMatcher, string modulePath)
        {
            foreach (var module in GetPSModuleInfo(modulePath))
            {
                var exportedTypes = module.GetExportedTypeDefinitions();

                ScriptBlockAst    ast     = null;
                TypeDefinitionAst typeAst = null;

                if (!_useWildCards)
                {
                    if (exportedTypes.TryGetValue(_className, out typeAst))
                    {
                        ast = typeAst.Parent.Parent as ScriptBlockAst;
                        if (ast != null)
                        {
                            return(ConvertToClassInfo(module, ast, typeAst));
                        }
                    }
                }
                else
                {
                    foreach (var exportedType in exportedTypes)
                    {
                        if (exportedType.Value != null &&
                            classNameMatcher.IsMatch(exportedType.Value.Name) &&
                            exportedType.Value.IsClass)
                        {
                            ast = exportedType.Value.Parent.Parent as ScriptBlockAst;
                            if (ast != null)
                            {
                                return(ConvertToClassInfo(module, ast, exportedType.Value));
                            }
                        }
                    }
                }
            }

            return(null);
        }
示例#5
0
 internal Scope(TypeDefinitionAst typeDefinition)
 {
     _ast           = typeDefinition;
     _scopeType     = ScopeType.Type;
     _typeTable     = new Dictionary <string, TypeLookupResult>(StringComparer.OrdinalIgnoreCase);
     _variableTable = new Dictionary <string, Ast>(StringComparer.OrdinalIgnoreCase);
     foreach (var member in typeDefinition.Members)
     {
         var propertyMember = member as PropertyMemberAst;
         if (propertyMember != null)
         {
             // Duplicate members are an error, but we catch that later after all types
             // have been resolved.  We could report errors for properties here, but
             // we couldn't compare methods because overloads can't be compared until types
             // are resolved.
             if (!_variableTable.ContainsKey(propertyMember.Name))
             {
                 _variableTable.Add(propertyMember.Name, propertyMember);
             }
         }
     }
 }
示例#6
0
        internal void AddType(Parser parser, TypeDefinitionAst typeDefinitionAst)
        {
            TypeLookupResult result;

            if (_typeTable.TryGetValue(typeDefinitionAst.Name, out result))
            {
                if (result.ExternalNamespaces != null)
                {
                    // override external type by the type defined in the current namespace
                    result.ExternalNamespaces = null;
                    result.Type = typeDefinitionAst;
                }
                else
                {
                    parser.ReportError(typeDefinitionAst.Extent, () => ParserStrings.MemberAlreadyDefined, typeDefinitionAst.Name);
                }
            }
            else
            {
                _typeTable.Add(typeDefinitionAst.Name, new TypeLookupResult(typeDefinitionAst));
            }
        }
示例#7
0
 internal Scope(TypeDefinitionAst typeDefinition)
 {
     _ast = typeDefinition;
     _scopeType = ScopeType.Type;
     _typeTable = new Dictionary<string, TypeLookupResult>(StringComparer.OrdinalIgnoreCase);
     _variableTable = new Dictionary<string, Ast>(StringComparer.OrdinalIgnoreCase);
     foreach (var member in typeDefinition.Members)
     {
         var propertyMember = member as PropertyMemberAst;
         if (propertyMember != null)
         {
             // Duplicate members are an error, but we catch that later after all types
             // have been resolved.  We could report errors for properties here, but
             // we couldn't compare methods because overloads can't be compared until types
             // are resolved.
             if (!_variableTable.ContainsKey(propertyMember.Name))
             {
                 _variableTable.Add(propertyMember.Name, propertyMember);
             }
         }
     }
 }
示例#8
0
        internal void AddTypeFromUsingModule(Parser parser, TypeDefinitionAst typeDefinitionAst, PSModuleInfo moduleInfo)
        {
            TypeLookupResult result;

            if (_typeTable.TryGetValue(typeDefinitionAst.Name, out result))
            {
                if (result.ExternalNamespaces != null)
                {
                    // override external type by the type defined in the current namespace
                    result.ExternalNamespaces.Add(moduleInfo.Name);
                }
            }
            else
            {
                var newLookupEntry = new TypeLookupResult(typeDefinitionAst)
                {
                    ExternalNamespaces = new List <string>()
                };
                newLookupEntry.ExternalNamespaces.Add(moduleInfo.Name);
                _typeTable.Add(typeDefinitionAst.Name, newLookupEntry);
            }

            string fullName = SymbolResolver.GetModuleQualifiedName(moduleInfo.Name, typeDefinitionAst.Name);

            if (_typeTable.TryGetValue(fullName, out result))
            {
                parser.ReportError(typeDefinitionAst.Extent,
                                   nameof(ParserStrings.MemberAlreadyDefined),
                                   ParserStrings.MemberAlreadyDefined,
                                   fullName);
            }
            else
            {
                _typeTable.Add(fullName, new TypeLookupResult(typeDefinitionAst));
            }
        }
示例#9
0
 public override object VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     _symbolResolver._symbolTable.LeaveScope();
     return null;
 }
示例#10
0
 public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     _symbolTable.EnterScope(typeDefinitionAst);
     return AstVisitAction.Continue;
 }
示例#11
0
 /// <summary>
 /// Add Type from the different module to the symbol Table.
 /// </summary>
 /// <param name="typeDefinitionAst"></param>
 /// <param name="moduleInfo"></param>
 public void AddTypeFromUsingModule(TypeDefinitionAst typeDefinitionAst, PSModuleInfo moduleInfo)
 {
     _scopes[_scopes.Count - 1].AddTypeFromUsingModule(_parser, typeDefinitionAst, moduleInfo);
 }
示例#12
0
 internal void EnterScope(TypeDefinitionAst typeDefinition)
 {
     var scope = new Scope(typeDefinition);
     _scopes.Add(scope);
     AddTypesInScope(typeDefinition);
 }
示例#13
0
 /// <summary/>
 public virtual AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst) => DefaultVisit(typeDefinitionAst);
示例#14
0
 public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     _symbolTable.EnterScope(typeDefinitionAst);
     return(AstVisitAction.Continue);
 }
示例#15
0
        /// <summary>
        /// Gets the line no for DSC Class Resource Get/Set/Test methods
        /// </summary>
        /// <param name="typeDefinitionAst"></param>
        /// <param name="methodsLinePosition"></param>
        private static bool GetResourceMethodsLineNumber(TypeDefinitionAst typeDefinitionAst, out Dictionary<string, int> methodsLinePosition)
        {
            const string getMethodName = "Get";
            const string setMethodName = "Set";
            const string testMethodName = "Test";

            methodsLinePosition = new Dictionary<string, int>(); ;
            foreach (var member in typeDefinitionAst.Members)
            {
                var functionMemberAst = member as FunctionMemberAst;
                if (functionMemberAst != null)
                {
                    if (functionMemberAst.Name.Equals(getMethodName, StringComparison.OrdinalIgnoreCase))
                    {
                        methodsLinePosition[getMethodName] = functionMemberAst.NameExtent.StartLineNumber;
                    }
                    else if (functionMemberAst.Name.Equals(setMethodName, StringComparison.OrdinalIgnoreCase))
                    {
                        methodsLinePosition[setMethodName] = functionMemberAst.NameExtent.StartLineNumber;
                    }
                    else if (functionMemberAst.Name.Equals(testMethodName, StringComparison.OrdinalIgnoreCase))
                    {
                        methodsLinePosition[testMethodName] = functionMemberAst.NameExtent.StartLineNumber;
                    }
                }
            }

            // All 3 methods (Get/Set/Test) position should be found.
            return (methodsLinePosition.Count == 3);
        }
示例#16
0
        private static void GenerateMofForAst(TypeDefinitionAst typeAst, StringBuilder sb, List<object> embeddedInstanceTypes)
        {
            var className = typeAst.Name;
            sb.AppendFormat(CultureInfo.InvariantCulture, "[ClassVersion(\"1.0.0\"), FriendlyName(\"{0}\")]\nclass {0}", className);

            if (typeAst.Attributes.Any(a => a.TypeName.GetReflectionAttributeType() == typeof(DscResourceAttribute)))
            {
                sb.Append(" : OMI_BaseResource");
            }
            sb.Append("\n{\n");

            ProcessMembers(sb, embeddedInstanceTypes, typeAst, className);

            Queue<object> bases = new Queue<object>();
            foreach (var b in typeAst.BaseTypes)
            {
                bases.Enqueue(b);
            }

            while (bases.Count > 0)
            {
                var b = bases.Dequeue();
                var tc = b as TypeConstraintAst;

                if (tc != null)
                {
                    b = tc.TypeName.GetReflectionType();
                    if (b == null)
                    {
                        var td = tc.TypeName as TypeName;
                        if (td != null && td._typeDefinitionAst != null)
                        {
                            ProcessMembers(sb, embeddedInstanceTypes, td._typeDefinitionAst, className);
                            foreach (var b1 in td._typeDefinitionAst.BaseTypes)
                            {
                                bases.Enqueue(b1);
                            }
                        }
                        continue;
                    }
                }

                var type = b as Type;
                if (type != null)
                {
                    ProcessMembers(type, sb, embeddedInstanceTypes, className);
                    var t = type.GetTypeInfo().BaseType;
                    if (t != null)
                    {
                        bases.Enqueue(t);
                    }
                }
            }

            sb.Append("};");
        }
示例#17
0
        internal static string GenerateMofForAst(TypeDefinitionAst typeAst)
        {
            var embeddedInstanceTypes = new List<object>();
            var sb = new StringBuilder();

            GenerateMofForAst(typeAst, sb, embeddedInstanceTypes);
            var visitedInstances = new List<object>();
            visitedInstances.Add(typeAst);
            ProcessEmbeddedInstanceTypes(embeddedInstanceTypes, visitedInstances, sb);

            return sb.ToString();
        }
示例#18
0
文件: PSType.cs 项目: 40a/PowerShell
 internal DefineEnumHelper(Parser parser, ModuleBuilder module, TypeDefinitionAst enumDefinitionAst, string typeName)
 {
     _parser = parser;
     _enumDefinitionAst = enumDefinitionAst;
     _moduleBuilder = module;
     _typeName = typeName;
 }
示例#19
0
文件: PSType.cs 项目: 40a/PowerShell
            /// <summary>
            /// Return base class type, never return null.
            /// </summary>
            /// <param name="parser"></param>
            /// <param name="typeDefinitionAst"></param>
            /// <param name="interfaces">return declared interfaces</param>
            /// <returns></returns>
            private Type GetBaseTypes(Parser parser, TypeDefinitionAst typeDefinitionAst, out List<Type> interfaces)
            {
                // Define base types and report errors.
                Type baseClass = null;
                interfaces = new List<Type>();

                // Default base class is System.Object and it has a default ctor.
                _baseClassHasDefaultCtor = true;
                if (typeDefinitionAst.BaseTypes.Any())
                {
                    // base class
                    var baseTypeAsts = typeDefinitionAst.BaseTypes;
                    var firstBaseTypeAst = baseTypeAsts[0];

                    if (firstBaseTypeAst.TypeName.IsArray)
                    {
                        parser.ReportError(firstBaseTypeAst.Extent, () => ParserStrings.SubtypeArray, firstBaseTypeAst.TypeName.FullName);
                        // fall to the default base type
                    }
                    else
                    {
                        baseClass = firstBaseTypeAst.TypeName.GetReflectionType();
                        if (baseClass == null)
                        {
                            parser.ReportError(firstBaseTypeAst.Extent, () => ParserStrings.TypeNotFound, firstBaseTypeAst.TypeName.FullName);
                            // fall to the default base type
                        }
                        else

                        {
                            if (baseClass.GetTypeInfo().IsSealed)
                            {
                                parser.ReportError(firstBaseTypeAst.Extent, () => ParserStrings.SealedBaseClass, baseClass.Name);
                                // ignore base type if it's sealed.
                                baseClass = null;
                            }
                            else if (baseClass.GetTypeInfo().IsGenericType && !baseClass.IsConstructedGenericType)
                            {
                                parser.ReportError(firstBaseTypeAst.Extent, () => ParserStrings.SubtypeUnclosedGeneric, baseClass.Name);
                                // ignore base type, we cannot inherit from unclosed generic.
                                baseClass = null;
                            }
                            else if (baseClass.GetTypeInfo().IsInterface)
                            {
                                // First Ast can represent interface as well as BaseClass.
                                interfaces.Add(baseClass);
                                baseClass = null;
                            }
                        }
                    }

                    if (baseClass != null)
                    {
                        // All PS classes are TypeName instances.
                        // For PS classes we cannot use reflection API, because type is not created yet.
                        var baseTypeName = firstBaseTypeAst.TypeName as TypeName;
                        if (baseTypeName != null)
                        {
                            _baseClassHasDefaultCtor = baseTypeName.HasDefaultCtor();
                        }
                        else
                        {
                            _baseClassHasDefaultCtor = baseClass.HasDefaultCtor();
                        }
                    }

                    for (int i = 0; i < baseTypeAsts.Count; i++)
                    {
                        if (baseTypeAsts[i].TypeName.IsArray)
                        {
                            parser.ReportError(baseTypeAsts[i].Extent, () => ParserStrings.SubtypeArray, baseTypeAsts[i].TypeName.FullName);
                            this.HasFatalErrors = true;
                        }
                    }

                    for (int i = 1; i < baseTypeAsts.Count; i++)
                    {
                        if (baseTypeAsts[i].TypeName.IsArray)
                        {
                            parser.ReportError(baseTypeAsts[i].Extent, () => ParserStrings.SubtypeArray, baseTypeAsts[i].TypeName.FullName);
                        }
                        else
                        {
                            Type interfaceType = baseTypeAsts[i].TypeName.GetReflectionType();
                            if (interfaceType == null)
                            {
                                parser.ReportError(baseTypeAsts[i].Extent, () => ParserStrings.TypeNotFound, baseTypeAsts[i].TypeName.FullName);
                            }
                            else
                            {
                                if (interfaceType.GetTypeInfo().IsInterface)
                                {
                                    interfaces.Add(interfaceType);
                                }
                                else
                                {
                                    parser.ReportError(baseTypeAsts[i].Extent, () => ParserStrings.InterfaceNameExpected, interfaceType.Name);
                                }
                            }
                        }
                    }
                }

                return baseClass ?? typeof(object);
            }
示例#20
0
文件: PSType.cs 项目: 40a/PowerShell
            public DefineTypeHelper(Parser parser, ModuleBuilder module, TypeDefinitionAst typeDefinitionAst, string typeName)
            {
                _moduleBuilder = module;
                _parser = parser;
                _typeDefinitionAst = typeDefinitionAst;

                List<Type> interfaces;
                var baseClass = this.GetBaseTypes(parser, typeDefinitionAst, out interfaces);

                _typeBuilder = module.DefineType(typeName, Reflection.TypeAttributes.Class | Reflection.TypeAttributes.Public, baseClass, interfaces.ToArray());
                _staticHelpersTypeBuilder = module.DefineType(string.Format(CultureInfo.InvariantCulture, "{0}_<staticHelpers>", typeName), Reflection.TypeAttributes.Class);
                DefineCustomAttributes(_typeBuilder, typeDefinitionAst.Attributes, _parser, AttributeTargets.Class);
                _typeDefinitionAst.Type = _typeBuilder.AsType();

                _fieldsToInitForMemberFunctions = new List<Tuple<string, object>>();
                _definedMethods = new Dictionary<string, List<Tuple<FunctionMemberAst, Type[]>>>(StringComparer.OrdinalIgnoreCase);
                _definedProperties = new Dictionary<string, PropertyMemberAst>(StringComparer.OrdinalIgnoreCase);

                _sessionStateField = _typeBuilder.DefineField(SessionStateFieldName, typeof(SessionStateInternal), FieldAttributes.Private);
                _sessionStateKeeperField = _staticHelpersTypeBuilder.DefineField(s_sessionStateKeeperFieldName, typeof(SessionStateKeeper), FieldAttributes.Assembly | FieldAttributes.Static);
            }
示例#21
0
 public object VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     throw PSTraceSource.NewArgumentException(nameof(typeDefinitionAst));
 }
示例#22
0
 public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst ast)
 {
     return(Check(ast));
 }
示例#23
0
        private static void ProcessMembers(StringBuilder sb, List<object> embeddedInstanceTypes, TypeDefinitionAst typeDefinitionAst, string className)
        {
            foreach (var member in typeDefinitionAst.Members)
            {
                var property = member as PropertyMemberAst;

                if (property == null || property.IsStatic ||
                    property.Attributes.All(a => a.TypeName.GetReflectionAttributeType() != typeof(DscPropertyAttribute)))
                {
                    continue;
                }

                var memberType = property.PropertyType == null
                    ? typeof(object)
                    : property.PropertyType.TypeName.GetReflectionType();

                var attributes = new List<object>();
                for (int i = 0; i < property.Attributes.Count; i++)
                {
                    attributes.Add(property.Attributes[i].GetAttribute());
                }

                string mofType;
                bool isArrayType;
                string embeddedInstanceType;
                string[] enumNames = null;

                if (memberType != null)
                {
                    // TODO - validate type and name
                    mofType = MapTypeToMofType(memberType, member.Name, className, out isArrayType,
                        out embeddedInstanceType,
                        embeddedInstanceTypes);
                    if (memberType.GetTypeInfo().IsEnum)
                    {
                        enumNames = Enum.GetNames(memberType);
                    }
                }
                else
                {
                    // PropertyType can't be null, we used typeof(object) above in that case so we don't get here.
                    mofType = MapTypeNameToMofType(property.PropertyType.TypeName, member.Name, className,
                        out isArrayType,
                        out embeddedInstanceType, embeddedInstanceTypes, ref enumNames);
                }
                string arrayAffix = isArrayType ? "[]" : String.Empty;

                sb.AppendFormat(CultureInfo.InvariantCulture,
                    "    {0}{1} {2}{3};\n",
                    MapAttributesToMof(enumNames, attributes, embeddedInstanceType),
                    mofType,
                    member.Name,
                    arrayAffix);
            }
        }
示例#24
0
 /// <summary>
 /// Add Type from the different module to the symbol Table.
 /// </summary>
 /// <param name="typeDefinitionAst"></param>
 /// <param name="moduleInfo"></param>
 public void AddTypeFromUsingModule(TypeDefinitionAst typeDefinitionAst, PSModuleInfo moduleInfo)
 {
     _scopes[_scopes.Count - 1].AddTypeFromUsingModule(_parser, typeDefinitionAst, moduleInfo);
 }
示例#25
0
        /// <summary>
        /// Check if it is a qualified DSC resource type
        /// </summary>
        /// <param name="parser"></param>
        /// <param name="typeDefinitionAst"></param>
        /// <param name="dscResourceAttributeAst"></param>
        internal static void CheckType(Parser parser, TypeDefinitionAst typeDefinitionAst, AttributeAst dscResourceAttributeAst)
        {
            bool hasSet = false;
            bool hasTest = false;
            bool hasGet = false;
            bool hasDefaultCtor = false;
            bool hasNonDefaultCtor = false;
            bool hasKey = false;

            Diagnostics.Assert(dscResourceAttributeAst != null, "CheckType called only for DSC resources. dscResourceAttributeAst must be non-null.");

            foreach (var member in typeDefinitionAst.Members)
            {
                var functionMemberAst = member as FunctionMemberAst;

                if (functionMemberAst != null)
                {
                    CheckSet(functionMemberAst, ref hasSet);
                    CheckGet(parser, functionMemberAst, ref hasGet);
                    CheckTest(functionMemberAst, ref hasTest);

                    if (functionMemberAst.IsConstructor && !functionMemberAst.IsStatic)
                    {
                        if (functionMemberAst.Parameters.Count == 0)
                        {
                            hasDefaultCtor = true;
                        }
                        else
                        {
                            hasNonDefaultCtor = true;
                        }
                    }
                }
                else
                {
                    var propertyMemberAst = (PropertyMemberAst)member;
                    CheckKey(parser, propertyMemberAst, ref hasKey);
                }
            }

            if (typeDefinitionAst.BaseTypes != null && (!hasSet || !hasGet || !hasTest || !hasKey))
            {
                LookupRequiredMembers(parser, typeDefinitionAst, ref hasSet, ref hasGet, ref hasTest, ref hasKey);
            }

            var name = typeDefinitionAst.Name;

            if (!hasSet)
            {
                parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingSetMethod, name);
            }

            if (!hasGet)
            {
                parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingGetMethod, name);
            }

            if (!hasTest)
            {
                parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingTestMethod, name);
            }

            if (!hasDefaultCtor && hasNonDefaultCtor)
            {
                parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingDefaultConstructor, name);
            }

            if (!hasKey)
            {
                parser.ReportError(dscResourceAttributeAst.Extent, () => ParserStrings.DscResourceMissingKeyProperty, name);
            }
        }
示例#26
0
文件: PSType.cs 项目: 40a/PowerShell
        private static string GetClassNameInAssembly(TypeDefinitionAst typeDefinitionAst)
        {
            // Only allocate a list if necessary - in the most common case, we don't need it.
            List<string> nameParts = null;
            var parent = typeDefinitionAst.Parent;
            while (parent.Parent != null)
            {
                if (parent is IParameterMetadataProvider)
                {
                    nameParts = nameParts ?? new List<string>();
                    var fnDefn = parent.Parent as FunctionDefinitionAst;
                    if (fnDefn != null)
                    {
                        parent = fnDefn;
                        nameParts.Add(fnDefn.Name);
                    }
                    else
                    {
                        nameParts.Add("<" + parent.Extent.Text.GetHashCode().ToString("x", CultureInfo.InvariantCulture) + ">");
                    }
                }
                parent = parent.Parent;
            }

            if (nameParts == null)
            {
                return typeDefinitionAst.Name;
            }

            nameParts.Reverse();
            nameParts.Add(typeDefinitionAst.Name);
            return string.Join(".", nameParts);
        }
示例#27
0
        /// <summary>
        /// Look up all the way up until find all the required members
        /// </summary>
        /// <param name="parser"></param>
        /// <param name="typeDefinitionAst">The type definition ast of the DSC resource type</param>
        /// <param name="hasSet">flag to indicate if the class contains Set method.</param>
        /// <param name="hasGet">flag to indicate if the class contains Get method.</param>
        /// <param name="hasTest">flag to indicate if the class contains Test method.</param>
        /// <param name="hasKey">flag to indicate if the class contains Key property.</param>
        private static void LookupRequiredMembers(Parser parser, TypeDefinitionAst typeDefinitionAst, ref bool hasSet, ref bool hasGet, ref bool hasTest, ref bool hasKey)
        {
            if (typeDefinitionAst == null)
            {
                return;
            }

            if (hasSet && hasGet && hasTest && hasKey)
            {
                return;
            }

            foreach (var baseType in typeDefinitionAst.BaseTypes)
            {
                var baseTypeName = baseType.TypeName as TypeName;
                if (baseTypeName == null)
                {
                    continue;
                }

                TypeDefinitionAst baseTypeDefinitionAst = baseTypeName._typeDefinitionAst;
                if (baseTypeDefinitionAst == null || !baseTypeDefinitionAst.IsClass)
                {
                    continue;
                }

                foreach (var member in baseTypeDefinitionAst.Members)
                {
                    var functionMemberAst = member as FunctionMemberAst;
                    if (functionMemberAst != null)
                    {
                        CheckSet(functionMemberAst, ref hasSet);
                        CheckGet(parser, functionMemberAst, ref hasGet);
                        CheckTest(functionMemberAst, ref hasTest);
                    }
                    else
                    {
                        var propertyMemberAst = (PropertyMemberAst)member;
                        CheckKey(parser, propertyMemberAst, ref hasKey);
                    }
                }
                if (baseTypeDefinitionAst.BaseTypes != null && (!hasSet || !hasGet || !hasTest || !hasKey))
                {
                    LookupRequiredMembers(parser, baseTypeDefinitionAst, ref hasSet, ref hasGet, ref hasTest, ref hasKey);
                }
            }
        }
示例#28
0
        internal void AddTypeFromUsingModule(Parser parser, TypeDefinitionAst typeDefinitionAst, PSModuleInfo moduleInfo)
        {
            TypeLookupResult result;
            if (_typeTable.TryGetValue(typeDefinitionAst.Name, out result))
            {
                if (result.ExternalNamespaces != null)
                {
                    // override external type by the type defined in the current namespace
                    result.ExternalNamespaces.Add(moduleInfo.Name);
                }
            }
            else
            {
                var newLookupEntry = new TypeLookupResult(typeDefinitionAst)
                {
                    ExternalNamespaces = new List<string>()
                };
                newLookupEntry.ExternalNamespaces.Add(moduleInfo.Name);
                _typeTable.Add(typeDefinitionAst.Name, newLookupEntry);
            }

            string fullName = SymbolResolver.GetModuleQualifiedName(moduleInfo.Name, typeDefinitionAst.Name);
            if (_typeTable.TryGetValue(fullName, out result))
            {
                parser.ReportError(typeDefinitionAst.Extent, () => ParserStrings.MemberAlreadyDefined, fullName);
            }
            else
            {
                _typeTable.Add(fullName, new TypeLookupResult(typeDefinitionAst));
            }
        }
示例#29
0
        public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
        {
            AttributeAst dscResourceAttibuteAst = null;
            for (int i = 0; i < typeDefinitionAst.Attributes.Count; i++)
            {
                var attr = typeDefinitionAst.Attributes[i];
                if (attr.TypeName.GetReflectionAttributeType() == typeof(DscResourceAttribute))
                {
                    dscResourceAttibuteAst = attr;
                    break;
                }
            }
            if (dscResourceAttibuteAst != null)
            {
                DscResourceChecker.CheckType(_parser, typeDefinitionAst, dscResourceAttibuteAst);
            }

            return AstVisitAction.Continue;
        }
示例#30
0
 /// <summary>
 /// Add Type to the symbol Table.
 /// </summary>
 /// <param name="typeDefinitionAst"></param>
 public void AddType(TypeDefinitionAst typeDefinitionAst)
 {
     _scopes[_scopes.Count - 1].AddType(_parser, typeDefinitionAst);
 }
示例#31
0
 /// <summary/>
 public virtual AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst) { return AstVisitAction.Continue; }
示例#32
0
 public TypeLookupResult(TypeDefinitionAst type = null)
 {
     Type = type;
 }
示例#33
0
        /// <summary>
        /// This constructor is used when the type is defined in PowerShell.
        /// </summary>
        /// <param name="typeDefinitionAst">The type definition from the ast.</param>
        public PSTypeName(TypeDefinitionAst typeDefinitionAst)
        {
            if (typeDefinitionAst == null)
            {
                throw PSTraceSource.NewArgumentNullException("typeDefinitionAst");
            }

            TypeDefinitionAst = typeDefinitionAst;
            Name = typeDefinitionAst.Name;
        }
示例#34
0
        // This is the main entry point for turning an AST into compiled code.
        internal void Compile(CompiledScriptBlockData scriptBlock, bool optimize)
        {
            var body = scriptBlock.Ast;
            Diagnostics.Assert(body is ScriptBlockAst || body is FunctionDefinitionAst || body is FunctionMemberAst || body is CompilerGeneratedMemberFunctionAst,
                               "Caller to verify ast is correct type.");
            var ast = (Ast)body;
            Optimize = optimize;
            _compilingScriptCmdlet = scriptBlock.UsesCmdletBinding;

            var fileName = ast.Extent.File;
            if (fileName != null)
            {
                _debugSymbolDocument = Expression.SymbolDocument(fileName);
            }

            var details = VariableAnalysis.Analyze(body, !optimize, _compilingScriptCmdlet);
            LocalVariablesTupleType = details.Item1;
            var nameToIndexMap = details.Item2;

            if (!nameToIndexMap.TryGetValue(SpecialVariables.@switch, out _switchTupleIndex))
            {
                _switchTupleIndex = VariableAnalysis.ForceDynamic;
            }
            if (!nameToIndexMap.TryGetValue(SpecialVariables.@foreach, out _foreachTupleIndex))
            {
                _foreachTupleIndex = VariableAnalysis.ForceDynamic;
            }

            LocalVariablesParameter = Expression.Variable(LocalVariablesTupleType, "locals");

            var functionMemberAst = ast as FunctionMemberAst;
            if (functionMemberAst != null)
            {
                CompilingMemberFunction = true;
                MemberFunctionReturnType = functionMemberAst.GetReturnType();
                _memberFunctionType = (TypeDefinitionAst)functionMemberAst.Parent;
                SpecialMemberFunctionType = SpecialMemberFunctionType.None;
                if (functionMemberAst.Name.Equals(_memberFunctionType.Name, StringComparison.OrdinalIgnoreCase))
                {
                    // TODO: default argument support
                    var parameters = ((IParameterMetadataProvider)functionMemberAst.Body).Parameters;
                    if (parameters == null || parameters.Count == 0)
                    {
                        SpecialMemberFunctionType = functionMemberAst.IsStatic
                            ? SpecialMemberFunctionType.StaticConstructor
                            : SpecialMemberFunctionType.DefaultConstructor;
                    }
                }
            }
            else
            {
                var generatedMemberFunctionAst = ast as CompilerGeneratedMemberFunctionAst;
                if (generatedMemberFunctionAst != null)
                {
                    CompilingMemberFunction = true;
                    SpecialMemberFunctionType = generatedMemberFunctionAst.Type;
                    MemberFunctionReturnType = typeof(void);
                    _memberFunctionType = generatedMemberFunctionAst.DefiningType;
                }
            }

            body.Body.Accept(this);

            if (_sequencePoints.Count == 0)
            {
                // Uncommon, but possible if a script is empty, or if it only defines functions.
                // In this case, add the entire body as a sequence point.  Debugging won't stop
                // on this sequence point, but it makes it safe to access the CurrentPosition
                // property in FunctionContext (which can happen if there are exceptions
                // defining the functions.)
                _sequencePoints.Add(ast.Extent);
            }

            var compileInterpretChoice = (_stmtCount > 300) ? CompileInterpretChoice.NeverCompile : CompileInterpretChoice.CompileOnDemand;

            if (optimize)
            {
                scriptBlock.DynamicParamBlock = CompileTree(_dynamicParamBlockLambda, compileInterpretChoice);
                scriptBlock.BeginBlock = CompileTree(_beginBlockLambda, compileInterpretChoice);
                scriptBlock.ProcessBlock = CompileTree(_processBlockLambda, compileInterpretChoice);
                scriptBlock.EndBlock = CompileTree(_endBlockLambda, compileInterpretChoice);
                scriptBlock.LocalsMutableTupleType = LocalVariablesTupleType;
                scriptBlock.LocalsMutableTupleCreator = MutableTuple.TupleCreator(LocalVariablesTupleType);
                scriptBlock.NameToIndexMap = nameToIndexMap;
            }
            else
            {
                scriptBlock.UnoptimizedDynamicParamBlock = CompileTree(_dynamicParamBlockLambda, compileInterpretChoice);
                scriptBlock.UnoptimizedBeginBlock = CompileTree(_beginBlockLambda, compileInterpretChoice);
                scriptBlock.UnoptimizedProcessBlock = CompileTree(_processBlockLambda, compileInterpretChoice);
                scriptBlock.UnoptimizedEndBlock = CompileTree(_endBlockLambda, compileInterpretChoice);
                scriptBlock.UnoptimizedLocalsMutableTupleType = LocalVariablesTupleType;
                scriptBlock.UnoptimizedLocalsMutableTupleCreator = MutableTuple.TupleCreator(LocalVariablesTupleType);
            }

            // The sequence points are identical optimized or not.  Regardless, we want to ensure
            // that the list is unique no matter when the property is accessed, so make sure it is set just once.
            if (scriptBlock.SequencePoints == null)
            {
                scriptBlock.SequencePoints = _sequencePoints.ToArray();
            }
        }
示例#35
0
        /// <summary>
        /// Bake types and creates a dynamic assembly. 
        /// This method should be called only for rootAsts (i.e. script file root ScriptBlockAst).
        /// </summary>
        /// <param name="rootForDefiningTypes"></param>
        /// <param name="typeAsts">non-empty array of TypeDefinitionAst</param>
        /// <returns>Assembly with defined types</returns>
        internal static Assembly DefinePowerShellTypes(Ast rootForDefiningTypes, TypeDefinitionAst[] typeAsts)
        {
            // TODO(sevoroby): this Diagnostic is conceptually right. 
            // BUT It triggers, when we define type in an InitialSessionState and use it later in two different PowerShell instances.
            // Diagnostics.Assert(typeAsts[0].Type == null, "We must not call DefinePowerShellTypes twice for the same TypeDefinitionAsts");

            if (typeAsts[0].Type != null)
            {
                // We treat Type as a mutable buffer field and wipe it here to start definitions from scratch.

                // I didn't find any real scenario when it can cause problems, except multi-threaded environment, which is rear and out-of-scope for now.
                // Potentially, we can fix it with Ast.Copy() and rewiring ITypeName references for the whole tree.
                foreach (var typeDefinitionAst in typeAsts)
                {
                    typeDefinitionAst.Type = null;
                }
            }

            // This is a short term solution - all error messages produced by creating the types should happen
            // at parse time, not runtime.
            var parser = new Parser();
            var assembly = TypeDefiner.DefineTypes(parser, rootForDefiningTypes, typeAsts);
            if (parser.ErrorList.Count > 0)
            {
                // wipe types, if there are any errors.
                foreach (var typeDefinitionAst in typeAsts)
                {
                    typeDefinitionAst.Type = null;
                }

                throw new ParseException(parser.ErrorList.ToArray());
            }

            return assembly;
        }
 object ICustomAstVisitor2.VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 => ProcessRewriter(VisitTypeDefinition, typeDefinitionAst);
示例#37
0
 public object VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     return ExpressionCache.Empty;
 }
示例#38
0
 /// <summary/>
 public virtual object VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     return(null);
 }
示例#39
0
 public override object VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     _symbolResolver._symbolTable.LeaveScope();
     return(null);
 }
示例#40
0
 public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     DiscoveredClasses.Add(typeDefinitionAst);
     return(_forCompletion ? AstVisitAction.Continue : AstVisitAction.SkipChildren);
 }
示例#41
0
 public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     DiscoveredClasses.Add(typeDefinitionAst);
     return _forCompletion ? AstVisitAction.Continue : AstVisitAction.SkipChildren;
 }
示例#42
0
 /// <summary>
 /// Add Type to the symbol Table.
 /// </summary>
 /// <param name="typeDefinitionAst"></param>
 public void AddType(TypeDefinitionAst typeDefinitionAst)
 {
     _scopes[_scopes.Count - 1].AddType(_parser, typeDefinitionAst);
 }
示例#43
0
 public object VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     return(false);
 }
示例#44
0
 public TypeLookupResult(TypeDefinitionAst type = null)
 {
     Type = type;
 }
 public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     return(Visit(typeDefinitionAst));
 }
示例#46
0
 public override StatementAst VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 => VisitStatement(base.VisitTypeDefinition(typeDefinitionAst));
示例#47
0
文件: PSType.cs 项目: 40a/PowerShell
        internal static Assembly DefineTypes(Parser parser, Ast rootAst, TypeDefinitionAst[] typeDefinitions)
        {
            Diagnostics.Assert(rootAst.Parent == null, "Caller should only define types from the root ast");

            var definedTypes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

            // First character is a special mark that allows us to cheaply ignore dynamic generated assemblies in ClrFacede.GetAssemblies()
            // Two replaces at the end are for not-allowed characters. They are replaced by similar-looking chars.
            string assemblyName = ClrFacade.FIRST_CHAR_PSASSEMBLY_MARK + (string.IsNullOrWhiteSpace(rootAst.Extent.File)
                                      ? "powershell"
                                      : rootAst.Extent.File
                                      .Replace('\\', (char)0x29f9)
                                      .Replace('/', (char)0x29f9)
                                      .Replace(':', (char)0x0589));

            var assembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(assemblyName),
                                                                 AssemblyBuilderAccess.RunAndCollect, GetAssemblyAttributeBuilders());
            var module = assembly.DefineDynamicModule(assemblyName);

            var defineTypeHelpers = new List<DefineTypeHelper>();
            var defineEnumHelpers = new List<DefineEnumHelper>();

            foreach (var typeDefinitionAst in typeDefinitions)
            {
                var typeName = GetClassNameInAssembly(typeDefinitionAst);
                if (!definedTypes.Contains(typeName))
                {
                    definedTypes.Add(typeName);
                    if ((typeDefinitionAst.TypeAttributes & TypeAttributes.Class) == TypeAttributes.Class)
                    {
                        defineTypeHelpers.Add(new DefineTypeHelper(parser, module, typeDefinitionAst, typeName));
                    }
                    else if ((typeDefinitionAst.TypeAttributes & TypeAttributes.Enum) == TypeAttributes.Enum)
                    {
                        defineEnumHelpers.Add(new DefineEnumHelper(parser, module, typeDefinitionAst, typeName));
                    }
                }
            }

            // Define enums before classes so members of classes can use these enum types.
            defineEnumHelpers = DefineEnumHelper.Sort(defineEnumHelpers, parser);
            foreach (var helper in defineEnumHelpers)
            {
                helper.DefineEnum();
            }

            foreach (var helper in defineTypeHelpers)
            {
                helper.DefineMembers();
            }

            foreach (var helper in defineTypeHelpers)
            {
                Diagnostics.Assert(helper._typeDefinitionAst.Type.GetTypeInfo() is TypeBuilder, "Type should be the TypeBuilder");
                bool runtimeTypeAssigned = false;
                if (!helper.HasFatalErrors)
                {
                    try
                    {
                        var type = helper._typeBuilder.CreateTypeInfo().AsType();
                        helper._typeDefinitionAst.Type = type;
                        runtimeTypeAssigned = true;
                        var helperType = helper._staticHelpersTypeBuilder.CreateTypeInfo().AsType();

                        if (helper._fieldsToInitForMemberFunctions != null)
                        {
                            foreach (var tuple in helper._fieldsToInitForMemberFunctions)
                            {
                                helperType.GetField(tuple.Item1, BindingFlags.NonPublic | BindingFlags.Static)
                                    .SetValue(null, tuple.Item2);
                            }
                        }

                        helperType.GetField(s_sessionStateKeeperFieldName, BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, new SessionStateKeeper());
                    }
                    catch (TypeLoadException e)
                    {
                        // This is a cheap way to get error messages about non-implemented abstract/interface methods (and maybe some other errors).
                        // We use .NET API to perform this check during type creation.
                        //
                        // Presumably this catch could go away when we will not create Type at parse time.
                        // Error checking should be moved/added to semantic checks.
                        parser.ReportError(helper._typeDefinitionAst.Extent, () => ParserStrings.TypeCreationError,
                            helper._typeBuilder.Name, e.Message);
                    }
                }

                if (!runtimeTypeAssigned)
                {
                    // Clean up ast
                    helper._typeDefinitionAst.Type = null;
                }
            }

            return assembly;
        }
示例#48
0
 /// <summary/>
 public virtual AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     return(AstVisitAction.Continue);
 }
        internal static Type GetTypeFromMemberExpressionAst(MemberExpressionAst memAst, VariableAnalysisDetails analysis, TypeDefinitionAst psClass)

        #endif        
        {
            if (memAst != null && memAst.Expression is VariableExpressionAst && memAst.Member is StringConstantExpressionAst
                && !String.Equals((memAst.Expression as VariableExpressionAst).VariablePath.UserPath, "this", StringComparison.OrdinalIgnoreCase))
            {
                string fieldName = (memAst.Member as StringConstantExpressionAst).Value;

                #if !PSV3

                if (psClass == null && analysis.Constant == SpecialVars.ThisVariable)
                {
                    psClass = AssignmentTarget.FindClassAncestor(memAst);
                }

                if (psClass != null)
                {
                    Type typeFromClass = AssignmentTarget.GetTypeFromClass(psClass, memAst);
                    {
                        if (typeFromClass != null)
                        {
                            return typeFromClass;
                        }
                    }
                }

                #endif

                // If the type is not a ps class or there are some types of the same name.
                if (analysis != null && analysis.Type != null && analysis.Type != typeof(object)
                    && analysis.Type != typeof(Unreached) && analysis.Type != typeof(Undetermined))
                {
                    if (memAst is InvokeMemberExpressionAst)
                    {
                        return AssignmentTarget.GetTypeFromInvokeMemberAst(analysis.Type, memAst as InvokeMemberExpressionAst, fieldName, false);
                    }
                    else
                    {
                        return AssignmentTarget.GetPropertyOrFieldTypeFromMemberExpressionAst(analysis.Type, fieldName);
                    }
                }
            }

            return null;
        }
示例#50
0
        private PSClassInfo ConvertToClassInfo(PSModuleInfo module, ScriptBlockAst ast, TypeDefinitionAst statement)
        {
            PSClassInfo classInfo = new PSClassInfo(statement.Name);

            Dbg.Assert(statement.Name != null, "statement should have a name.");
            classInfo.Module = module;
            Collection <PSClassMemberInfo> properties = new Collection <PSClassMemberInfo>();

            foreach (var member in statement.Members)
            {
                if (member is PropertyMemberAst propAst && !propAst.PropertyAttributes.HasFlag(PropertyAttributes.Hidden))
                {
                    Dbg.Assert(propAst.Name != null, "PropName cannot be null");
                    Dbg.Assert(propAst.PropertyType != null, "PropertyType cannot be null");
                    Dbg.Assert(propAst.PropertyType.TypeName != null, "Property TypeName cannot be null");
                    Dbg.Assert(propAst.Extent != null, "Property Extent cannot be null");
                    Dbg.Assert(propAst.Extent.Text != null, "Property ExtentText cannot be null");

                    PSClassMemberInfo classProperty = new PSClassMemberInfo(propAst.Name,
                                                                            propAst.PropertyType.TypeName.FullName,
                                                                            propAst.Extent.Text);
                    properties.Add(classProperty);
                }
            }

            classInfo.UpdateMembers(properties);

            string mamlHelpFile = null;

            if (ast.GetHelpContent() != null)
            {
                mamlHelpFile = ast.GetHelpContent().MamlHelpFile;
            }

            if (!string.IsNullOrEmpty(mamlHelpFile))
            {
                classInfo.HelpFile = mamlHelpFile;
            }

            return(classInfo);
        }
        /// <summary>
        /// Get the type for memberexpressionast assuming that the variable is a class
        /// </summary>
        /// <param name="psClass"></param>
        /// <param name="memberExpressionAst"></param>
        /// <returns></returns>
        internal static Type GetTypeFromClass(TypeDefinitionAst psClass, MemberExpressionAst memberExpressionAst)
        {
            Type result = null;

            if (psClass != null)
            {
                MemberAst memAst = psClass.Members.FirstOrDefault(item => String.Equals(item.Name, (memberExpressionAst.Member as StringConstantExpressionAst).Value, StringComparison.OrdinalIgnoreCase));

                if (memAst != null)
                {
                    if (memAst is PropertyMemberAst)
                    {
                        result = (memAst as PropertyMemberAst).PropertyType.TypeName.GetReflectionType();
                    }
                    else if (memAst is FunctionMemberAst)
                    {
                        result = (memAst as FunctionMemberAst).ReturnType.TypeName.GetReflectionType();
                    }
                }
            }

            return result;
        }
示例#52
0
 public object VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst)
 {
     return(AutomationNull.Value);
 }
示例#53
0
 public override AstVisitAction VisitTypeDefinition(TypeDefinitionAst typeDefinitionAst) => VisitAst(typeDefinitionAst);