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); }
public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) //confirmed { if (functionMemberAst.ToString().Contains(symbolRef.ScriptRegion.Text)) { ValidateExtend(symbolRef.ScriptRegion.Text, functionMemberAst.Name, functionMemberAst); } return(base.VisitFunctionMember(functionMemberAst)); }
public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) { if (!ValidateExtend(symbolRef.ScriptRegion.Text, functionMemberAst.Name, functionMemberAst)) { return(AstVisitAction.Continue); } return(AstVisitAction.StopVisit); }
public virtual MemberAst VisitFunctionMember(FunctionMemberAst functionMemberAst) { return(new FunctionMemberAst( functionMemberAst.Extent, new FunctionDefinitionAst( functionMemberAst.Extent, false, false, functionMemberAst.Name, functionMemberAst.Parameters?.RewriteAll(this, SyntaxKind.Parameter), functionMemberAst.Body?.Rewrite(this, SyntaxKind.ScriptBlock)), functionMemberAst.ReturnType.Rewrite(this, SyntaxKind.TypeConstraint), functionMemberAst.Attributes?.RewriteAll(this), functionMemberAst.MethodAttributes)); }
public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) { string description; var helpResult = HelpTableQuery("about_classes"); var attributes = functionMemberAst.Attributes.Count > 0 ? $", with attributes '{string.Join(", ", functionMemberAst.Attributes.Select(m => m.TypeName.Name))}'." : "."; if (functionMemberAst.IsConstructor) { StringBuilder parameterSignature = new(); foreach (var par in functionMemberAst.Parameters) { parameterSignature .Append(par.StaticType.Name) .Append(' ') .Append(par.Name.VariablePath.UserPath) .Append(", "); } parameterSignature.Remove(parameterSignature.Length - 2, 2); var howManyParameters = functionMemberAst.Parameters.Count == 0 ? string.Empty : $"has {functionMemberAst.Parameters.Count} parameters and "; description = $"A constructor, a special method, used to set things up within the object. Constructors have the same name as the class. This constructor {howManyParameters}is called when [{(functionMemberAst.Parent as TypeDefinitionAst).Name}]::new({parameterSignature}) is used."; helpResult.DocumentationLink += "#constructor"; } else { helpResult.DocumentationLink += "#class-methods"; var modifier = "M"; modifier = functionMemberAst.IsHidden ? "A hidden m" : modifier; modifier = functionMemberAst.IsStatic ? "A static m" : modifier; description = $"{modifier}ethod '{functionMemberAst.Name}' that returns type '{functionMemberAst.ReturnType.TypeName.FullName}'{attributes}"; } explanations.Add(new Explanation() { Description = description, CommandName = "Method member", HelpResult = helpResult, TextToHighlight = functionMemberAst.Name }.AddDefaults(functionMemberAst, explanations)); return(base.VisitFunctionMember(functionMemberAst)); }
public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) => VisitAst(functionMemberAst);
public object VisitFunctionMember(FunctionMemberAst functionMemberAst) { return(false); }
public object VisitFunctionMember(FunctionMemberAst functionMemberAst) { throw PSTraceSource.NewArgumentException(nameof(functionMemberAst)); }
public override object VisitFunctionMember(FunctionMemberAst functionMemberAst) { _symbolResolver._symbolTable.LeaveScope(); return null; }
public object VisitFunctionMember(FunctionMemberAst functionMemberAst) { throw new System.NotImplementedException(); }
public override MemberAst VisitFunctionMember(FunctionMemberAst functionMemberAst) => VisitOther(base.VisitFunctionMember(functionMemberAst));
/// <summary> /// Check if it is a Get method with correct return type and signature /// </summary> /// <param name="parser"></param> /// <param name="functionMemberAst">The function member AST</param> /// <param name="hasGet">True if it is a Get method with qualified return type and signature; otherwise, false. </param> private static void CheckGet(Parser parser, FunctionMemberAst functionMemberAst, ref bool hasGet) { if (hasGet) { return; } if (functionMemberAst.Name.Equals("Get", StringComparison.OrdinalIgnoreCase) && functionMemberAst.Parameters.Count == 0) { if (functionMemberAst.ReturnType != null) { // Return type is of the class we're defined in //it must return the class type, or array of the class type. var arrayTypeName = functionMemberAst.ReturnType.TypeName as ArrayTypeName; var typeName = (arrayTypeName != null ? arrayTypeName.ElementType : functionMemberAst.ReturnType.TypeName) as TypeName; if (typeName == null || typeName._typeDefinitionAst != functionMemberAst.Parent) { parser.ReportError(functionMemberAst.Extent, () => ParserStrings.DscResourceInvalidGetMethod, ((TypeDefinitionAst)functionMemberAst.Parent).Name); } } else { parser.ReportError(functionMemberAst.Extent, () => ParserStrings.DscResourceInvalidGetMethod, ((TypeDefinitionAst)functionMemberAst.Parent).Name); } //Set hasGet to true to stop look up; it may have invalid get hasGet = true; return; } }
private void DefineMethod(FunctionMemberAst functionMemberAst) { var parameterTypes = GetParameterTypes(functionMemberAst); if (parameterTypes == null) { // There must have been an error, just return return; } if (CheckForDuplicateOverload(functionMemberAst, parameterTypes)) { return; } if (functionMemberAst.IsConstructor) { var methodAttributes = Reflection.MethodAttributes.Public; if (functionMemberAst.IsStatic) { var parameters = functionMemberAst.Parameters; if (parameters.Count > 0) { _parser.ReportError(Parser.ExtentOf(parameters.First(), parameters.Last()), () => ParserStrings.StaticConstructorCantHaveParameters); return; } methodAttributes |= Reflection.MethodAttributes.Static; } DefineConstructor(functionMemberAst, functionMemberAst.Attributes, functionMemberAst.IsHidden, methodAttributes, parameterTypes); return; } var attributes = functionMemberAst.IsPublic ? Reflection.MethodAttributes.Public : Reflection.MethodAttributes.Private; if (functionMemberAst.IsStatic) { attributes |= Reflection.MethodAttributes.Static; } else { if (this.MethodExistsOnBaseClassAndFinal(functionMemberAst.Name, parameterTypes)) { attributes |= Reflection.MethodAttributes.HideBySig; attributes |= Reflection.MethodAttributes.NewSlot; } attributes |= Reflection.MethodAttributes.Virtual; } var returnType = functionMemberAst.GetReturnType(); if (returnType == null) { _parser.ReportError(functionMemberAst.ReturnType.Extent, () => ParserStrings.TypeNotFound, functionMemberAst.ReturnType.TypeName.FullName); return; } var method = _typeBuilder.DefineMethod(functionMemberAst.Name, attributes, returnType, parameterTypes); DefineCustomAttributes(method, functionMemberAst.Attributes, _parser, AttributeTargets.Method); if (functionMemberAst.IsHidden) { method.SetCustomAttribute(s_hiddenCustomAttributeBuilder); } var ilGenerator = method.GetILGenerator(); DefineMethodBody(functionMemberAst, ilGenerator, GetMetaDataName(method.Name, parameterTypes.Count()), functionMemberAst.IsStatic, parameterTypes, returnType, (i, n) => method.DefineParameter(i, ParameterAttributes.None, n)); }
private Type[] GetParameterTypes(FunctionMemberAst functionMemberAst) { var parameters = ((IParameterMetadataProvider)functionMemberAst).Parameters; if (parameters == null) { return PSTypeExtensions.EmptyTypes; } bool anyErrors = false; var result = new Type[parameters.Count]; for (var i = 0; i < parameters.Count; i++) { var typeConstraint = parameters[i].Attributes.OfType<TypeConstraintAst>().FirstOrDefault(); var paramType = (typeConstraint != null) ? typeConstraint.TypeName.GetReflectionType() : typeof(object); if (paramType == null) { _parser.ReportError(typeConstraint.Extent, () => ParserStrings.TypeNotFound, typeConstraint.TypeName.FullName); anyErrors = true; } else if (paramType == typeof(void) || paramType.GetTypeInfo().IsGenericTypeDefinition) { _parser.ReportError(typeConstraint.Extent, () => ParserStrings.TypeNotAllowedForParameter, typeConstraint.TypeName.FullName); anyErrors = true; } result[i] = paramType; } return anyErrors ? null : result; }
private bool CheckForDuplicateOverload(FunctionMemberAst functionMemberAst, Type[] newParameters) { List<Tuple<FunctionMemberAst, Type[]>> overloads; if (!_definedMethods.TryGetValue(functionMemberAst.Name, out overloads)) { overloads = new List<Tuple<FunctionMemberAst, Type[]>>(); _definedMethods.Add(functionMemberAst.Name, overloads); } else { foreach (var overload in overloads) { var overloadParameters = overload.Item2; // This test won't be correct when defaults are supported if (newParameters.Length != overloadParameters.Length) { continue; } var sameSignature = true; for (int i = 0; i < newParameters.Length; i++) { if (newParameters[i] != overloadParameters[i]) { sameSignature = false; break; } } if (sameSignature) { // If both are both static/instance, it's an error. // Otherwise, signatures can match only for the constructor. if (overload.Item1.IsStatic == functionMemberAst.IsStatic || !functionMemberAst.IsConstructor) { _parser.ReportError(functionMemberAst.NameExtent ?? functionMemberAst.Extent, () => ParserStrings.MemberAlreadyDefined, functionMemberAst.Name); return true; } } } } overloads.Add(Tuple.Create(functionMemberAst, newParameters)); return false; }
object ICustomAstVisitor2.VisitFunctionMember(FunctionMemberAst functionMemberAst) => ProcessRewriter(VisitFunctionMember, functionMemberAst);
/// <summary> /// Check if it is a Test method with correct return type and signature /// </summary> /// <param name="functionMemberAst">The function member AST</param> /// <param name="hasTest">True if it is a Test method with qualified return type and signature; otherwise, false.</param> private static void CheckTest(FunctionMemberAst functionMemberAst, ref bool hasTest) { if (hasTest) return; hasTest = (functionMemberAst.Name.Equals("Test", StringComparison.OrdinalIgnoreCase) && functionMemberAst.Parameters.Count == 0 && functionMemberAst.ReturnType != null && functionMemberAst.ReturnType.TypeName.GetReflectionType() == typeof(bool)); }
/// <summary> /// Analyze a member function, marking variable references as "dynamic" (so they can be reported as errors) /// and also analyze the control flow to make sure every block returns (or throws) /// </summary> /// <param name="ast"></param> /// <returns></returns> internal static bool AnalyzeMemberFunction(FunctionMemberAst ast) { VariableAnalysis va = (new VariableAnalysis()); va.AnalyzeImpl(ast, false, false); return va._exitBlock._predecessors.All(b => b._returns || b._throws || b._unreachable); }
/// <summary> /// Check if it is a Set method with correct return type and signature /// </summary> /// <param name="functionMemberAst">The function member AST</param> /// <param name="hasSet">True if it is a Set method with qualified return type and signature; otherwise, false.</param> private static void CheckSet(FunctionMemberAst functionMemberAst, ref bool hasSet) { if (hasSet) return; hasSet = (functionMemberAst.Name.Equals("Set", StringComparison.OrdinalIgnoreCase) && functionMemberAst.Parameters.Count == 0 && functionMemberAst.IsReturnTypeVoid()); }
/// <summary/> public virtual AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) => DefaultVisit(functionMemberAst);
public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) { _memberScopeStack.Push(functionMemberAst); var body = functionMemberAst.Body; if (body.ParamBlock != null) { _parser.ReportError(body.ParamBlock.Extent, () => ParserStrings.ParamBlockNotAllowedInMethod); } if (body.BeginBlock != null || body.ProcessBlock != null || body.DynamicParamBlock != null || !body.EndBlock.Unnamed) { _parser.ReportError(Parser.ExtentFromFirstOf(body.DynamicParamBlock, body.BeginBlock, body.ProcessBlock, body.EndBlock), () => ParserStrings.NamedBlockNotAllowedInMethod); } if (functionMemberAst.IsConstructor && functionMemberAst.ReturnType != null) { _parser.ReportError(functionMemberAst.ReturnType.Extent, () => ParserStrings.ConstructorCantHaveReturnType); } // Analysis determines if all paths return and do data flow for variables. var allCodePathsReturned = VariableAnalysis.AnalyzeMemberFunction(functionMemberAst); if (!allCodePathsReturned && !functionMemberAst.IsReturnTypeVoid()) { _parser.ReportError(functionMemberAst.NameExtent ?? functionMemberAst.Extent, () => ParserStrings.MethodHasCodePathNotReturn); } return AstVisitAction.Continue; }
public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) { _symbolTable.EnterScope(functionMemberAst.Body, ScopeType.Method); return AstVisitAction.Continue; }
public override AstVisitAction VisitFunctionMember(FunctionMemberAst ast) { return(Check(ast)); }
/// <summary> /// AnalyzeDSCClass: Analyzes given DSC Resource /// </summary> /// <param name="ast"></param> /// <param name="fileName"></param> /// <returns></returns> public IEnumerable <DiagnosticRecord> AnalyzeDSCClass(Ast ast, string fileName) { if (ast == null) { throw new ArgumentNullException(Strings.NullAstErrorMessage); } IEnumerable <TypeDefinitionAst> classes = ast.FindAll(item => item is TypeDefinitionAst && ((item as TypeDefinitionAst).IsClass), true).Cast <TypeDefinitionAst>(); IEnumerable <TypeDefinitionAst> dscClasses = classes.Where(item => (item as TypeDefinitionAst).Attributes.Any(attr => String.Equals("DSCResource", attr.TypeName.FullName, StringComparison.OrdinalIgnoreCase))); List <string> resourceFunctionNames = new List <string>(new string[] { "Test", "Get", "Set" }); foreach (TypeDefinitionAst dscClass in dscClasses) { Dictionary <string, string> returnTypes = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); returnTypes["Test"] = typeof(bool).FullName; returnTypes["Get"] = dscClass.Name; foreach (var member in dscClass.Members) { FunctionMemberAst funcAst = member as FunctionMemberAst; if (funcAst == null || !resourceFunctionNames.Contains(funcAst.Name, StringComparer.OrdinalIgnoreCase)) { continue; } if (!String.Equals(funcAst.Name, "Set") && !Helper.Instance.AllCodePathReturns(funcAst)) { yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.NotAllCodePathReturnsDSCFunctionsError, funcAst.Name, dscClass.Name), funcAst.Extent, GetName(), DiagnosticSeverity.Information, fileName)); } if (String.Equals(funcAst.Name, "Set")) { IEnumerable <Ast> returnStatements = funcAst.FindAll(item => item is ReturnStatementAst, true); foreach (ReturnStatementAst ret in returnStatements) { if (ret.Pipeline != null) { yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.ReturnCorrectTypesForSetFunctionsDSCError, dscClass.Name), funcAst.Extent, GetName(), DiagnosticSeverity.Information, fileName)); } } } if (returnTypes.ContainsKey(funcAst.Name)) { IEnumerable <Ast> returnStatements = funcAst.FindAll(item => item is ReturnStatementAst, true); Type type = funcAst.ReturnType.TypeName.GetReflectionType(); foreach (ReturnStatementAst ret in returnStatements) { if (ret.Pipeline == null) { yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.ReturnCorrectTypesForDSCFunctionsNoTypeError, funcAst.Name, dscClass.Name, returnTypes[funcAst.Name]), ret.Extent, GetName(), DiagnosticSeverity.Information, fileName)); } string typeName = Helper.Instance.GetTypeFromReturnStatementAst(funcAst, ret, classes); // This also includes the case of return $this because the type of this is unreached. if (String.IsNullOrEmpty(typeName) || String.Equals(typeof(Unreached).FullName, typeName, StringComparison.OrdinalIgnoreCase) || String.Equals(typeof(Undetermined).FullName, typeName, StringComparison.OrdinalIgnoreCase) || String.Equals(typeof(object).FullName, typeName, StringComparison.OrdinalIgnoreCase) || String.Equals(returnTypes[funcAst.Name], typeName, StringComparison.OrdinalIgnoreCase)) { continue; } else { yield return(new DiagnosticRecord(string.Format(CultureInfo.CurrentCulture, Strings.ReturnCorrectTypesForDSCFunctionsWrongTypeError, funcAst.Name, dscClass.Name, returnTypes[funcAst.Name], typeName), ret.Extent, GetName(), DiagnosticSeverity.Information, fileName)); } } } } } }
public override object VisitFunctionMember(FunctionMemberAst functionMemberAst) { _symbolResolver._symbolTable.LeaveScope(); return(null); }
/// <summary/> public virtual object VisitFunctionMember(FunctionMemberAst functionMemberAst) { return(null); }
public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) { return(Visit(functionMemberAst)); }
public override AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) { _symbolTable.EnterScope(functionMemberAst.Body, ScopeType.Method); return(AstVisitAction.Continue); }
/// <summary/> public virtual AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) { return AstVisitAction.Continue; }
/// <summary/> public virtual AstVisitAction VisitFunctionMember(FunctionMemberAst functionMemberAst) { return(AstVisitAction.Continue); }
public object VisitFunctionMember(FunctionMemberAst functionMemberAst) { return null; }
public object VisitFunctionMember(FunctionMemberAst functionMemberAst) { return(AutomationNull.Value); }
public override AstVisitAction VisitFunctionMember(FunctionMemberAst ast) { return Check(ast); }