public void Analyze(CallSignature/*!*/node, Analyzer/*!*/ analyzer, RoutineSignature/*!*/ signature, ExInfoFromParent info, bool isBaseCtorCallConstrained) { // generic: foreach (var p in node.GenericParams) TypeRefHelper.Analyze(p, analyzer); // regular: analyzer.EnterActualParams(signature, node.Parameters.Count); foreach (var p in node.Parameters) p.NodeCompiler<ActualParamCompiler>().Analyze(p, analyzer, isBaseCtorCallConstrained); analyzer.LeaveActualParams(); }
public static void Analyze(this CallSignature/*!*/node, Analyzer/*!*/ analyzer, RoutineSignature/*!*/ signature, ExInfoFromParent info, bool isBaseCtorCallConstrained) { node.NodeCompiler<ICallSignatureCompiler>().Analyze(node, analyzer, signature, info, isBaseCtorCallConstrained); }
///// <summary> ///// Determines whether specified signatures are compatible, i.e. ///// one of them is unknown or their param. counts are the same and type hints are the same. ///// </summary> //public static bool AreCompatible(PhpRoutineSignature sig1, PhpRoutineSignature sig2) //{ // // signature not known => assume ok (for some system methods): // if (sig1 == null || sig2 == null) return true; // // different return types: // if (sig1.AliasReturn != sig2.AliasReturn) return false; // // different parameter counts: // if (sig1.ParamCount != sig2.ParamCount) return false; // for (int i = 0; i < sig1.ParamCount; i++) // { // if (sig1.aliasMask[i] != sig2.aliasMask[i] || sig1.typeHints[i] != sig2.typeHints[i]) // return false; // } // return true; //} /// <summary> /// Determines whether this signature can override given signature. /// Parameters count, type hints and names must match. /// </summary> /// <param name="sig"></param> /// <returns>True if method with this signature can override method with given signature.</returns> internal override bool CanOverride( RoutineSignature sig ) { if (!base.CanOverride(sig)) return false; PhpRoutineSignature phpsig = sig as PhpRoutineSignature; if (phpsig != null) { if (this.TypeHints.Length < phpsig.TypeHints.Length) return false; // parameters by ref as it is in base declaration ? for (int i = 0; i < phpsig.AliasMask.Count; ++i) if (this.IsAlias(i) != phpsig.IsAlias(i)) return false; // different type hints? for (int i = 0; i < phpsig.TypeHints.Length; ++i) { DType hintType = this.TypeHints[i]; DType hintBaseType = phpsig.GetTypeHint(i); if (hintType == null || hintBaseType == null) continue; // skip this now, we don't know some type hint, or it has not been specified ... // TODO: in some cases Phalanger does not remember type hints (e.g. abstract class in external file ?) string hintName = (hintType != null) ? hintType.FullName.ToLower() : null; string hintBaseName = (hintBaseType != null) ? hintBaseType.FullName.ToLower() : null; if (hintName != hintBaseName) return false; } } return true; }
internal void Analyze(Analyzer/*!*/ analyzer, RoutineSignature/*!*/ signature, ExInfoFromParent info, bool isBaseCtorCallConstrained) { // generic: for (int i = 0; i < genericParams.Count; i++) genericParams[i].Analyze(analyzer); // regular: analyzer.EnterActualParams(signature, parameters.Count); for (int i = 0; i < parameters.Count; i++) parameters[i].Analyze(analyzer, isBaseCtorCallConstrained); analyzer.LeaveActualParams(); }
internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position, out RoutineSignature overloadSignature) { overloadSignature = UnknownSignature.Default; return 0; }
internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position, out RoutineSignature overloadSignature) { // no ctor defined => default is to be used => should have no parameters; // do not report errors if the declaring type is open type (constructed or a generic parameter); if (declaringType.IsDefinite && IsConstructor && declaringType.IsClosed && callSignature.Parameters.Count > 0) { analyzer.ErrorSink.Add(Warnings.NoCtorDefined, analyzer.SourceUnit, position, declaringType.FullName); declaringType.ReportError(analyzer.ErrorSink, Warnings.RelatedLocation); } overloadSignature = UnknownSignature.Default; return 0; }
internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position, out RoutineSignature/*!*/ overloadSignature) { if (overloads.Count == 0) { if (DeclaringType.TypeDesc is ClrDelegateDesc) { overloadSignature = UnknownSignature.Delegate; return 0; } // structures without ctor: if (DeclaringType.TypeDesc.RealType.IsValueType) { overloadSignature = UnknownSignature.Default; return 0; } Debug.Assert(this.IsConstructor, "Only constructors can have no overload."); overloadSignature = UnknownSignature.Default; return DRoutine.InvalidOverloadIndex; } int i = 0; bool found = false; Overload overload; while (i < overloads.Count && (overload = overloads[i]).MandatoryParamCount <= callSignature.Parameters.Count) { if (overload.MandatoryParamCount == callSignature.Parameters.Count || (overload.Flags & OverloadFlags.IsVararg) != 0) { found = true; break; } i++; } // TODO: by type resolving // evaluate arguments? if (!found) { analyzer.ErrorSink.Add(Warnings.InvalidArgumentCountForMethod, analyzer.SourceUnit, position, this.DeclaringType.FullName, this.FullName); if (i > 0) i--; overloadSignature = overloads[i]; return i; } overloadSignature = overloads[i]; return i; }
internal override int ResolveOverload(Analyzer analyzer, CallSignature callSignature, Position position, out RoutineSignature overloadSignature) { overloadSignature = signature; return 0; }
/// <summary> /// Finds most suitable overload. Returns <see cref="InvalidOverloadIndex"/> and /// <see cref="UnknownSignature.Default"/> in <c>overloadSignature</c> if no suitable overload exists. /// </summary> internal abstract int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position, out RoutineSignature overloadSignature);
internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position, out RoutineSignature overloadSignature) { if (callSignature.GenericParams.Count > 0) { analyzer.ErrorSink.Add(Errors.GenericCallToLibraryFunction, analyzer.SourceUnit, position); callSignature = new CallSignature(callSignature.Parameters, TypeRef.EmptyList); } bool exact_match; int result = ResolveOverload(callSignature.Parameters.Count, out exact_match); if (!exact_match) { // library function with wrong number of actual arguments: analyzer.ErrorSink.Add(Errors.InvalidArgumentCountForFunction, analyzer.SourceUnit, position, FullName); } overloadSignature = overloads[result]; return result; }
internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position, out RoutineSignature overloadSignature) { if (callSignature.Parameters.Count < signature.MandatoryParamCount) { if (IsConstructor) { analyzer.ErrorSink.Add(Warnings.TooFewCtorParameters, analyzer.SourceUnit, position, DeclaringType.FullName, signature.MandatoryParamCount, callSignature.Parameters.Count); } else if (IsStatic) { analyzer.ErrorSink.Add(Warnings.TooFewMethodParameters, analyzer.SourceUnit, position, DeclaringType.FullName, this.FullName, signature.MandatoryParamCount.ToString(), callSignature.Parameters.Count.ToString()); } } overloadSignature = signature; return 0; }
internal override int ResolveOverload(Analyzer/*!*/ analyzer, CallSignature callSignature, Position position, out RoutineSignature overloadSignature) { if (callSignature.Parameters.Count < signature.MandatoryParamCount) { analyzer.ErrorSink.Add(Warnings.TooFewFunctionParameters, analyzer.SourceUnit, position, qualifiedName, signature.MandatoryParamCount, callSignature.Parameters.Count); } overloadSignature = signature; return 0; }
/// <summary> /// Determines whether this signature can override given signature. /// Parameters count, type hints and names must match. /// </summary> /// <param name="sig"></param> /// <returns></returns> internal virtual bool CanOverride(RoutineSignature sig) { // additional parameters must have default value // all arguments in base method with default value has the default value in overriding (this) method return (sig != null && sig.AliasReturn == this.AliasReturn && sig.ParamCount <= this.ParamCount && sig.MandatoryParamCount == this.MandatoryParamCount); }
internal void EnterActualParams(RoutineSignature/*!*/ signature, int actualParamCount) { locationStack.Push(new ActualParamsLocation(signature, actualParamCount)); }
internal ActualParamsLocation(RoutineSignature/*!*/ signature, int actualParamCount) { this.currentParam = -1; this.signature = signature; this.actualParamCount = actualParamCount; }