def _compile(self): """ Compile the language specification: perform legality checks and type inference. """ # Compile the first time, do nothing next times if self.compiled: return self.compiled = True assert self.grammar, "Set grammar before compiling" if not self.grammar.rules.get(self.main_rule_name, None): close_matches = difflib.get_close_matches( self.main_rule_name, self.grammar.rules.keys() ) with self.grammar.context(): check_source_language( False, 'Invalid rule name specified for main rule: "{}". ' '{}'.format( self.main_rule_name, 'Did you mean "{}"?'.format(close_matches[0]) if close_matches else "" ) ) unreferenced_rules = self.grammar.get_unreferenced_rules() check_source_language( not unreferenced_rules, "The following parsing rules are not " "used: {}".format(", ".join(sorted(unreferenced_rules))), severity=Severity.warning ) # Compute type information, so that it is available for further # compilation stages. self.compute_types() errors_checkpoint() if self.verbosity.info: printcol("Compiling the grammar...", Colors.OKBLUE) with names.camel_with_underscores: # Compute the type of fields for types used in the grammar for r_name, r in self.grammar.rules.items(): r.compute_fields_types() # Compute properties information, so that it is available for # further compilation stages. self.compute_properties() errors_checkpoint() for r_name, r in self.grammar.rules.items(): r.compile() self.rules_to_fn_names[r_name] = r unresolved_types = set([t for t in self.astnode_types if not t.is_type_resolved]) check_source_language( not unresolved_types, "The following ASTNode subclasses are not type resolved. They are" " not used by the grammar, and their types not annotated:" " {}".format(", ".join(t.name().camel for t in unresolved_types)) ) astnodes_files = { path.abspath(inspect.getsourcefile(n)) for n in self.astnode_types } if self.annotate_fields_types: # Only import lib2to3 if the users needs it import lib2to3.main lib2to3.main.main( "langkit", ["-f", "annotate_fields_types", "--no-diff", "-w"] + list(astnodes_files) ) for i, astnode in enumerate( (astnode for astnode in self.astnode_types if not astnode.abstract), # Compute kind constants for all ASTNode concrete subclasses. # Start with 2: the constant 0 is reserved as an # error/uninitialized code and the constant 1 is reserved for all # ASTList nodes. start=2 ): self.node_kind_constants[astnode] = i # Now that all Struct subclasses referenced by the grammar have been # typed, iterate over all declared subclasses to register the ones that # are unreachable from the grammar. TODO: this kludge will eventually # disappear as part of OC22-016. for t in self.struct_types + self.astnode_types: t.add_to_context() errors_checkpoint()
:param pass_fn: Function to be run when executing the pass. Called once per PropertyDef instance. This function must take the PropertyDef instance and the context. :type (langkit.expressions.base.PropertyDef, langkit.compile_context.CompileCtx) -> None :param bool disabled: See AbstractPass. """ super(PropertyPass, self).__init__(name, disabled) self.pass_fn = pass_fn def run(self, context): for prop in context.all_properties(include_inherited=False): with prop.diagnostic_context: self.pass_fn(prop, context) class StopPipeline(AbstractPass): """ Dummy concrete pass to abort the execution of a pipeline. Used with the "disabled" attribute, this is useful to conditionnaly limit the set of passes to be executed. """ pass errors_checkpoint_pass = GlobalPass('errors checkpoint', lambda _: errors_checkpoint())
def _compile(self, compile_only=False): """ Compile the language specification: perform legality checks and type inference. """ # Compile the first time, do nothing next times if self.compiled: return self.compiled = True assert self.grammar, "Set grammar before compiling" if not self.grammar.rules.get(self.main_rule_name, None): close_matches = difflib.get_close_matches( self.main_rule_name, self.grammar.rules.keys()) with self.grammar.context(): check_source_language( False, 'Invalid rule name specified for main rule: "{}". ' '{}'.format( self.main_rule_name, 'Did you mean "{}"?'.format( close_matches[0]) if close_matches else "")) unreferenced_rules = self.grammar.get_unreferenced_rules() check_source_language(not unreferenced_rules, "The following parsing rules are not " "used: {}".format(", ".join( sorted(unreferenced_rules))), severity=Severity.warning) if self.verbosity.info: printcol("Compiling the grammar...", Colors.OKBLUE) with names.camel_with_underscores: # Compute the type of fields for types used in the grammar. Also # register its symbol literals. for r_name, r in self.grammar.rules.items(): with r.error_context(): r.compute_fields_types() for sym in r.symbol_literals: self.add_symbol_literal(sym) # Compute type information, so that it is available for further # compilation stages. self.compute_types() errors_checkpoint() with names.camel_with_underscores: # Compute properties information, so that it is available for # further compilation stages. self.compute_properties(compile_only=compile_only) errors_checkpoint() # Past this point, the set of symbol literals is frozen self.finalize_symbol_literals() unresolved_types = set( [t for t in self.astnode_types if not t.is_type_resolved]) check_source_language( not unresolved_types, "The following ASTNode subclasses are not type resolved. They are" " not used by the grammar, and their types not annotated:" " {}".format(", ".join(t.name().camel for t in unresolved_types))) astnodes_files = { path.abspath(inspect.getsourcefile(n)) for n in self.astnode_types } if compile_only: return with names.camel_with_underscores: for r_name, r in self.grammar.rules.items(): with r.error_context(): r.compile() if self.annotate_fields_types: # Only import lib2to3 if the users needs it import lib2to3.main lib2to3.main.main( "langkit", ["-f", "annotate_fields_types", "--no-diff", "-w"] + list(astnodes_files)) for i, astnode in enumerate( (astnode for astnode in self.astnode_types if not astnode.abstract), # Compute kind constants for all ASTNode concrete subclasses. # Start with 1: the constant 0 is reserved as an # error/uninitialized code. start=1): self.node_kind_constants[astnode] = i # Now that all Struct subclasses referenced by the grammar have been # typed, iterate over all declared subclasses to register the ones that # are unreachable from the grammar. TODO: this kludge will eventually # disappear as part of OC22-016. for t in self.struct_types + self.astnode_types: t.add_to_context() errors_checkpoint()