public void Report(ErrorSink/*!*/ sink) { if (sink == null) throw new ArgumentNullException("sink"); if (name != null) sink.Add(FatalErrors.InvalidCommandLineArgument, null, Parsers.Position.Invalid, name, Message); else sink.Add(FatalErrors.InvalidCommandLineArgumentNoName, null, Parsers.Position.Invalid, Message); }
public void Report(ErrorSink /*!*/ errorSink) { if (errorSink == null) { throw new ArgumentNullException("errorSink"); } errorSink.Add(FatalErrors.InvalidSource, path, ErrorPosition.Invalid, InnerException != null ? InnerException.Message : this.Message); }
/// <summary> /// Compiles an application. /// </summary> /// <param name="applicationContext">Application context.</param> /// <param name="config">Compiler configuration record.</param> /// <param name="errorSink">Error sink.</param> /// <param name="ps">Parameters.</param> /// <exception cref="InvalidSourceException">Cannot read a source file/directory. See the inner exception for details.</exception> public void Compile( ApplicationContext/*!*/ applicationContext, CompilerConfiguration/*!*/ config, ErrorSink/*!*/ errorSink, CompilationParameters/*!*/ ps) { if (applicationContext == null) throw new ArgumentNullException("applicationContext"); if (config == null) throw new ArgumentNullException("config"); if (errorSink == null) throw new ArgumentNullException("errorSink"); ps.Validate(); PhpSourceFile entry_point_file = (ps.StartupFile != null) ? new PhpSourceFile(config.Compiler.SourceRoot, ps.StartupFile) : null; List<ResourceFileReference> resource_files = ResourceFileReference.FromFiles(ps.Resources); // creates directory if not exists: try { Directory.CreateDirectory(Path.GetDirectoryName(ps.OutPath)); } catch (Exception ex) { errorSink.Add(FatalErrors.ErrorCreatingFile, null, ErrorPosition.Invalid, ps.OutPath, ex.Message); } AssemblyKinds kind; switch (ps.Target) { case Targets.Dll: kind = AssemblyKinds.Library; entry_point_file = null; break; case Targets.Console: kind = AssemblyKinds.ConsoleApplication; break; case Targets.WinApp: kind = AssemblyKinds.WindowApplication; break; case Targets.Web: kind = AssemblyKinds.WebPage; entry_point_file = null; break; default: throw new ArgumentException(); } PhpAssemblyBuilder assembly_builder = PhpAssemblyBuilder.Create(applicationContext, kind, ps.Pure, ps.OutPath, ps.DocPath, entry_point_file, ps.Version, ps.Key, ps.Icon, resource_files, config.Compiler.Debug, ps.Force32Bit); assembly_builder.IsMTA = ps.IsMTA; Statistics.CompilationStarted(); ICompilerManager manager = (!ps.Pure) ? new ApplicationCompilerManager(applicationContext, assembly_builder) : null; try { CompilationContext context = new CompilationContext(applicationContext, manager, config, errorSink, config.Compiler.SourceRoot); assembly_builder.Build(EnumerateScripts(ps.SourcePaths, ps.SourceDirs, ps.FileExtensions, context), context); if (!context.Errors.AnyError && (ps.Target == Targets.Console || ps.Target == Targets.WinApp)) CopyApplicationConfigFile(config.Compiler.SourceRoot, ps.OutPath); } catch (CompilerException e) { errorSink.Add(e.ErrorInfo, null, ErrorPosition.Invalid, e.ErrorParams); } catch (InvalidSourceException e) { e.Report(errorSink); } catch (Exception e) { #if DEBUG //Console.WriteLine("Unexpected error: {0}", e.ToString());// removed, exception added into the error sink, so it's displayed in the VS Integration too #endif errorSink.AddInternalError(e); // compilation will fail, error will be displayed in Errors by VS Integration } finally { #if DEBUG Console.WriteLine(); Console.WriteLine("Statistics:"); Statistics.Dump(Console.Out, Path.GetDirectoryName(ps.OutPath)); Console.WriteLine(); #endif } }
internal void ValidateOverride(ErrorSink/*!*/ errors, KnownProperty/*!*/ overridden) { Debug.Assert(sourceUnit != null, "Not applicable on reflected properties"); // TODO: // string overridden_field_pos = String.Concat(overridden_field.Class.FullSourcePath, overridden_field.Position); // static field cannot be made non static if (overridden.IsStatic && !this.IsStatic) { errors.Add(Errors.MakeStaticPropertyNonStatic, SourceUnit, Position, overridden.DeclaringType.FullName, this.Name.ToString(), this.DeclaringType.FullName); } // decrease visibility is prohibited if ((overridden.IsPublic && (this.IsPrivate || this.IsProtected)) || (overridden.IsProtected && (this.IsPrivate))) { errors.Add(Errors.OverridingFieldRestrictsVisibility, SourceUnit, Position, overridden.DeclaringType.FullName, this.Name.ToString(), overridden.Visibility.ToString().ToLowerInvariant(), this.DeclaringType.FullName); } // // field non-staticness non-overridable // if (!overridden_field.FieldModifiers.IsStatic && field.FieldModifiers.IsStatic) // { // classesTable.Errors.Add(Errors.MakeNonStaticFieldStatic, classesTable.SourceFile, field.Position, // overridden_field_class.Name.ToString(), field.FieldName.ToString(), Name.ToString(), overridden_field_pos); // } // // overriding field visibility // if ((overridden_field.FieldModifiers.IsPublic && !field.FieldModifiers.IsPublic) // || (overridden_field.FieldModifiers.IsProtected && !field.FieldModifiers.IsProtected && !field.FieldModifiers.IsPublic)) // { // classesTable.Errors.Add(Errors.OverridingFieldRestrictsVisibility, classesTable.SourceFile, field.Position, // Name.ToString(), field.FieldName.ToString(), overridden_field.FieldModifiers.VisibilityToString(), overridden_field_class.Name.ToString(), overridden_field_pos); // } // // protected and public static field overriding // if (overridden_field.FieldModifiers.IsStatic && field.FieldModifiers.IsStatic // && ((overridden_field.FieldModifiers.IsProtected && field.FieldModifiers.IsProtected) // || (overridden_field.FieldModifiers.IsPublic && field.FieldModifiers.IsPublic))) // { // classesTable.Errors.Add(Errors.OverridingStaticFieldByStatic, classesTable.SourceFile, field.Position, overridden_field_class.Name.ToString(), // field.FieldName.ToString(), Name.ToString(), field.FieldModifiers.VisibilityToString(), overridden_field_pos); // } // // protected static field initial value // // we can check only first field overrided in the hierarchy. If the overrided field is protected, // // this field must be public (otherwise previous exception has been thrown), so there is not other // // protected field in the hierarchy above. // if (field.FieldModifiers.IsStatic && field.HasInitValue && field.FieldModifiers.IsPublic && // overridden_field.FieldModifiers.IsStatic && overridden_field.HasInitValue && overridden_field.FieldModifiers.IsProtected) // { // classesTable.Errors.Add(Errors.OverridingProtectedStaticWithInitValue, classesTable.SourceFile, field.Position, // overridden_field_class.Name.ToString(), field.FieldName.ToString(), Name.ToString(), overridden_field_pos); // } // // if this field increases visibility of inherited field, set class from where is the field accessible from IL // if (field.FieldModifiers.IsPublic && overridden_field.FieldModifiers.IsProtected) // field.SetImplementClass(overridden_field_class); }
internal void Validate(SourceUnit/*!*/ sourceUnit, ErrorSink/*!*/ errors) { Debug.Assert(position.IsValid); // no abstract fields: if (IsAbstract) { errors.Add(Errors.PropertyDeclaredAbstract, SourceUnit, position); memberDesc.MemberAttributes &= ~PhpMemberAttributes.Abstract; } // no final fields: if (IsFinal) { errors.Add(Errors.PropertyDeclaredFinal, SourceUnit, position); memberDesc.MemberAttributes &= ~PhpMemberAttributes.Final; } }
internal override void ReportError(ErrorSink/*!*/ sink, ErrorInfo error) { if (sourceUnit != null) sink.Add(error, SourceUnit, position); }
internal override void ReportAbstractNotImplemented(ErrorSink/*!*/ errors, DType/*!*/ declaringType, PhpType/*!*/ referringType) { errors.Add(Errors.AbstractPropertyNotImplemented, referringType.Declaration.SourceUnit, referringType.Declaration.Position, referringType.FullName, declaringType.MakeFullGenericName(), this.FullName); ReportError(errors, Errors.RelatedLocation); }
internal void ValidateBody(ErrorSink/*!*/ errors) { // checks whether there are too many local variables (warning only): if (builder.LocalVariables.Count > VariablesTable.SuboptimalLocalsCount) { properties |= RoutineProperties.HasUnoptimizedLocals; if (IsMethod) { errors.Add(Warnings.TooManyLocalVariablesInMethod, SourceUnit, Position, DeclaringType.FullName, FullName, builder.LocalVariables.Count.ToString()); } else { errors.Add(Warnings.TooManyLocalVariablesInFunction, SourceUnit, Position, FullName, builder.LocalVariables.Count.ToString()); } } // check labels: Analyzer.ValidateLabels(errors, SourceUnit, builder.Labels); }
internal void ValidateOverride(ErrorSink/*!*/ errors, KnownRoutine/*!*/ overridden) { Debug.Assert(errors != null && overridden != null); Debug.Assert(sourceUnit != null, "Not applicable on reflected routines"); // final method cannot be overridden: if (overridden.IsFinal) { errors.Add(Errors.OverrideFinalMethod, SourceUnit, position, DeclaringType.FullName, this.FullName); overridden.ReportError(errors, Errors.RelatedLocation); } // cannot override non-abstract method by abstract: if (this.IsAbstract && !overridden.IsAbstract) { errors.Add(Errors.OverridingNonAbstractMethodByAbstract, SourceUnit, position, overridden.DeclaringType.FullName, overridden.FullName, DeclaringType.FullName); overridden.ReportError(errors, Errors.RelatedLocation); } // restricting method visibility: if ((overridden.IsPublic && !IsPublic || overridden.IsProtected && !this.IsProtected && !this.IsPublic) && // visibility of .ctor in CLR base can be restricted: !(overridden.DeclaringType.IsClrType && overridden.IsConstructor)) { errors.Add(Errors.OverridingMethodRestrictsVisibility, SourceUnit, position, DeclaringType.FullName, this.FullName, Enums.VisibilityToString(overridden.MemberDesc.MemberAttributes), overridden.DeclaringType.FullName); overridden.ReportError(errors, Errors.RelatedLocation); } // method staticness non-overridable: if (overridden.IsStatic && !this.IsStatic) { errors.Add(Errors.MakeStaticMethodNonStatic, SourceUnit, position, overridden.DeclaringType.FullName, overridden.FullName, DeclaringType.FullName); overridden.ReportError(errors, Errors.RelatedLocation); } // method non-staticness non-overridable: if (!overridden.IsStatic && this.IsStatic) { errors.Add(Errors.MakeNonStaticMethodStatic, SourceUnit, position, overridden.DeclaringType.FullName, overridden.FullName, DeclaringType.FullName); overridden.ReportError(errors, Errors.RelatedLocation); } // strict standards: function reference // Declaration of bar::a() should be compatible with that of foo::a() // This check is not performed for __construct() function in PHP. if (!Signature.CanOverride(overridden.GetSignature(0)) && !this.Name.IsConstructName) { errors.Add(Warnings.DeclarationShouldBeCompatible, SourceUnit, position, DeclaringType.FullName, this.FullName, overridden.DeclaringType.FullName, overridden.FullName); /*PhpException.Throw(PhpError.Strict, CoreResources.GetString("declaration_should_be_compatible", DeclaringType.FullName, this.FullName, overridden.DeclaringType.FullName, overridden.FullName));*/ } }
internal override void ReportMethodNotCompatible(ErrorSink errors, DType declaringType, PhpType referringType) { errors.Add(Errors.MethodNotCompatible, referringType.Declaration.SourceUnit, referringType.Declaration.Position, referringType.FullName, this.FullName, declaringType.MakeFullGenericName(), this.FullName); //ReportError(errors, Errors.RelatedLocation); }
internal void Validate(ErrorSink/*!*/ errors) { if (hasBody) { // make sure that interface methods have no bodies: if (DeclaringType.IsInterface) { errors.Add(Errors.InterfaceMethodWithBody, sourceUnit, position, DeclaringType.FullName, this.FullName); } else if (IsAbstract) // all methods in interfaces are abstract { // make sure that abstract methods have no bodies errors.Add(Errors.AbstractMethodWithBody, sourceUnit, position, DeclaringType.FullName, this.FullName); MemberDesc.MemberAttributes &= ~PhpMemberAttributes.Abstract; } } else { // make sure that non-abstract methods have bodies if (!IsAbstract) { errors.Add(Errors.NonAbstractMethodWithoutBody, sourceUnit, position, DeclaringType.FullName, this.FullName); MemberDesc.MemberAttributes |= PhpMemberAttributes.Abstract; } } if (this.IsConstructor) { // constructor non-staticness: if (IsStatic) { errors.Add(Errors.ConstructCannotBeStatic, sourceUnit, position, DeclaringType.FullName, this.FullName); MemberDesc.MemberAttributes &= ~PhpMemberAttributes.Static; } // no generic parameters on ctor: if (signature.GenericParamCount > 0) { errors.Add(Errors.ConstructorWithGenericParameters, sourceUnit, position, DeclaringType.FullName, this.FullName); // generic arguments needn't to be removed } } else if (this.Name.IsCloneName) { // clone argumentless-ness if (signature != null && signature.ParamCount > 0) errors.Add(Errors.CloneCannotTakeArguments, sourceUnit, position, DeclaringType.FullName); // clone non-staticness if (IsStatic) { errors.Add(Errors.CloneCannotBeStatic, sourceUnit, position, DeclaringType.FullName); RoutineDesc.MemberAttributes &= ~PhpMemberAttributes.Final; } } else if (this.Name.IsDestructName) { // destructor argumentless-ness if (signature != null && signature.ParamCount > 0) errors.Add(Errors.DestructCannotTakeArguments, sourceUnit, position, DeclaringType.FullName); // destructor non-staticness if (IsStatic) { errors.Add(Errors.DestructCannotBeStatic, sourceUnit, position, DeclaringType.FullName); MemberDesc.MemberAttributes &= ~PhpMemberAttributes.Static; } } else if (this.Name.IsCallName || this.Name.IsCallStaticName) { // check visibility & staticness if (this.Name.IsCallName && (this.IsStatic || !this.IsPublic)) errors.Add(Warnings.MagicMethodMustBePublicNonStatic, sourceUnit, position, this.Name.Value); if (this.Name.IsCallStaticName && (!this.IsStatic || !this.IsPublic)) errors.Add(Warnings.CallStatMustBePublicStatic, sourceUnit, position); // check args count if (signature != null && signature.ParamCount != 2) { errors.Add(FatalErrors.MethodMustTakeExacArgsCount, sourceUnit, position, this.DeclaringType.FullName, this.Name.Value, 2); } } else if (this.Name.IsToStringName) { if (IsStatic || !IsPublic) errors.Add(Warnings.MagicMethodMustBePublicNonStatic, sourceUnit, position, this.Name.Value); if (signature != null && signature.ParamCount != 0) errors.Add(Errors.MethodCannotTakeArguments, sourceUnit, position, this.DeclaringType.FullName, this.Name.Value); } // no final abstract member: if (IsAbstract && IsFinal) { errors.Add(Errors.AbstractFinalMethodDeclared, sourceUnit, position); MemberDesc.MemberAttributes &= ~((hasBody) ? PhpMemberAttributes.Final : PhpMemberAttributes.Abstract); } // no private abstract member: if (IsAbstract && IsPrivate) { errors.Add(Errors.AbstractPrivateMethodDeclared, sourceUnit, position); MemberDesc.MemberAttributes &= ~((hasBody) ? PhpMemberAttributes.Private : PhpMemberAttributes.Abstract); } // no non-public interface methods if (DeclaringType.IsInterface && (IsPrivate || IsProtected)) { errors.Add(Errors.InterfaceMethodNotPublic, sourceUnit, position, DeclaringType.FullName, this.FullName); MemberDesc.MemberAttributes &= ~PhpMemberAttributes.VisibilityMask; MemberDesc.MemberAttributes |= PhpMemberAttributes.Public; } }
public void ReportRedeclaration(ErrorSink/*!*/ errors) { Debug.Assert(declaration != null); errors.Add(FatalErrors.FunctionRedeclared, declaration.SourceUnit, declaration.Position, FullName); }
internal override void ReportError(ErrorSink/*!*/ sink, ErrorInfo error) { if (declaration != null) sink.Add(error, declaration.SourceUnit, declaration.Position); }
internal static void ValidateLabels(ErrorSink/*!*/ errors, SourceUnit/*!*/ sourceUnit, Dictionary<VariableName, Statement>/*!*/ labels) { foreach (KeyValuePair<VariableName, Statement> entry in labels) { LabelStmt label = entry.Value as LabelStmt; if (label != null) { if (!label.IsReferred) errors.Add(Warnings.UnusedLabel, sourceUnit, label.Position, entry.Key); } else { errors.Add(Errors.UndefinedLabel, sourceUnit, entry.Value.Position, entry.Key); } } }
public void Report(ErrorSink/*!*/ errorSink) { if (errorSink == null) throw new ArgumentNullException("errorSink"); errorSink.Add(FatalErrors.InvalidSource, path, ErrorPosition.Invalid, InnerException != null ? InnerException.Message : this.Message); }