/// <include file='Doc/Nodes.xml' path='doc/method[@name="Statement.Analyze"]/*'/> internal override Statement Analyze(Analyzer/*!*/ analyzer) { // remove classes that has been merged to the aggregate from the further processing: if (IsPartialMergeResiduum) return EmptyStmt.PartialMergeResiduum; // functions in incomplete (not emitted) class can't be emitted type.Declaration.IsInsideIncompleteClass = analyzer.IsInsideIncompleteClass(); // the ClassDecl is fully analyzed even if it will be replaced in the AST by EvalEx // and even if it is unreachable in order to discover all possible errors in compile-time type.Declaration.IsUnreachable = analyzer.IsThisCodeUnreachable(); if (type.Declaration.IsUnreachable) analyzer.ReportUnreachableCode(position); attributes.Analyze(analyzer, this); typeSignature.Analyze(analyzer); analyzer.EnterTypeDecl(type); foreach (var member in members) { member.EnterAnalyzer(analyzer); member.Analyze(analyzer); member.LeaveAnalyzer(analyzer); } analyzer.LeaveTypeDecl(); AnalyzeDocComments(analyzer); // validate the type after all members has been analyzed and validated: type.Validate(analyzer.ErrorSink); if (type.Declaration.IsUnreachable) { // only a conditional declaration can be unreachable // => not emiting the declaration is ok return EmptyStmt.Unreachable; } else if (!type.IsComplete) { // mark all functions declared in incomplete class as 'non-compilable' // convert incomplete class to an eval if applicable: if (analyzer.SourceUnit.CompilationUnit.IsPure && analyzer.CurrentType == null && analyzer.CurrentRoutine == null) { // error, since there is no place for global code in pure mode: analyzer.ErrorSink.Add(Errors.IncompleteClass, analyzer.SourceUnit, position, this.name); return this; } if (analyzer.SourceUnit.CompilationUnit.IsTransient) { TransientCompilationUnit transient_unit = (TransientCompilationUnit)analyzer.SourceUnit.CompilationUnit; // report an error only for synthetic evals as we are 100% sure that the class cannot be completed; // note that a synthetic eval can be created even in transient code as some base types could be // declared there conditionally: if (transient_unit.EvalKind == EvalKinds.SyntheticEval) { analyzer.ErrorSink.Add(Errors.IncompleteClass, analyzer.SourceUnit, position, this.name); return this; } } // report the warning, incomplete_class analyzer.ErrorSink.Add(Warnings.IncompleteClass, analyzer.SourceUnit, position, this.name); this.typeDefinitionCode = analyzer.SourceUnit.GetSourceCode(entireDeclarationPosition); //// we return an eval //EvalEx evalEx = new EvalEx( // entireDeclarationPosition, this.typeDefinitionCode, // (this.Namespace != null && this.Namespace.QualifiedName.Namespaces.Length > 0) ? this.Namespace.QualifiedName : (QualifiedName?)null, // this.validAliases); //Statement stmt = new ExpressionStmt(entireDeclarationPosition, evalEx); //// this annotation is for the duck-type generation - we need to know the original typedecl //evalEx.Annotations.Set<TypeDecl>(this); //return stmt; // we emit eval return this; } else { return this; } }