What the visitor do when a node is visited

Concrete visitors should implement this method. @toimplement

Property definitions

nitc $ Visitor :: visit
	# What the visitor do when a node is visited
	# Concrete visitors should implement this method.
	# @toimplement
	protected fun visit(e: ANode) is abstract
src/parser/parser_nodes.nit:462,2--465,42

nitc $ LiteralVisitor :: visit
	redef fun visit(n)
	do
		n.accept_literal(self)
		n.visit_all(self)
	end
src/literal.nit:48,2--52,4

nitc $ AnnotationPhaseVisitor :: visit
	redef fun visit(n)
	do
		n.visit_all(self)
		if n isa AAnnotation then annotations.add n
	end
src/phase.nit:200,2--204,4

nitc $ CollectTokensByTextVisitor :: visit
	redef fun visit(node)
	do
		node.visit_all(self)
		if node isa Token and node.text == text then result.add(node)
	end
src/parser/parser_nodes.nit:167,2--171,4

nitc $ CollectAnnotationsByNameVisitor :: visit
	redef fun visit(node)
	do
		node.visit_all(self)
		if node isa AAnnotation and node.n_atid.n_id.text == name then result.add(node)
	end
src/parser/parser_nodes.nit:178,2--182,4

nitc $ ComputeProdLocationVisitor :: visit
	redef fun visit(n: ANode)
	do
		if n isa Token then
			# Skip injected tokens
			if not isset n._location then return

			# Collect loose tokens (not in the AST) and attach them to token in the AST
			var cursor = token
			if n != cursor then
				var lt = last_token
				# In order, we have the tokens:
				# * `lt` the previous visited token in the AST (if any)
				# * then `cursor` the loose tokens to attach
				# * then `n` the current visited token in the AST

				# In the following, we advance `cursor` to add them to `lt.next_looses` or to `n.prev_looses`.
				if lt != null then
					var ltl = lt.location.line_end
					# floating tokens on the same line of a AST-token follows it
					while cursor != null and cursor != n and ltl == cursor.location.line_start do
						cursor.is_loose = true
						lt.next_looses.add cursor
						cursor = cursor.next_token
					end
				end
				# other loose tokens precede the next AST-token
				while cursor != null and cursor != n do
					cursor.is_loose = true
					n.prev_looses.add cursor
					cursor = cursor.next_token
				end
			end
			token = n.next_token

			var loc = n._location
			_last_token = n

			# Add a first token to productions that need one
			if not _need_first_prods.is_empty then
				for no in _need_first_prods do
					no._first_location = loc
				end
				_need_first_prods.clear
			end

			# Find location for already visited epsilon production that need one
			if not _need_after_epsilons.is_empty then
				var loco = new Location(loc.file, loc.line_start, loc.line_start, loc.column_start, loc.column_start) 
				for no in _need_after_epsilons do
					no.location = loco
				end
				_need_after_epsilons.clear
			end
		else
			assert n isa Prod
			_need_first_prods.add(n)

			n.visit_all(self)

			var startl = n._first_location
			if startl != null then
				# Non-epsilon production
				var endl = _last_token.location

				if startl == endl then
					n.location = startl
				else
					n.location = new Location(startl.file, startl.line_start, endl.line_end, startl.column_start, endl.column_end)
				end

				if not _need_after_epsilons.is_empty then
					var loc = new Location(endl.file, endl.line_end, endl.line_end, endl.column_end, endl.column_end)
					for no in _need_after_epsilons do
						# Epsilon production that finishes the current non-epsilon production
						no.location = loc
					end
					_need_after_epsilons.clear
				end
			else
				# Epsilon production in the middle or that finishes a parent non-epsilon production
				_need_after_epsilons.add(n)
			end
		end
	end
src/parser/parser_work.nit:193,2--276,4

nitc $ TextCollectorVisitor :: visit
	redef fun visit(n)
	do
		if n isa Token then text += n.text
		n.visit_all(self)
	end
src/parser/parser_work.nit:282,2--286,4

nitc $ AutoSuperInitVisitor :: visit
	redef fun visit(n)
	do
		n.accept_auto_super_init(self)
		n.visit_all(self)
	end
src/semantize/auto_super_init.nit:36,2--40,4

nitc $ PostTypingVisitor :: visit
	redef fun visit(n) do
		n.visit_all(self)
		n.accept_post_typing(type_visitor)
		if n isa AExpr and n.mtype == null and not n.is_typed then
			n.is_broken = true
		end
	end
src/semantize/typing.nit:942,2--948,4

nitc $ LocalVarInitVisitor :: visit
	redef fun visit(n)
	do
		n.accept_local_var_visitor(self)
	end
src/semantize/local_var_init.nit:79,2--82,4

nitc $ FlowVisitor :: visit
	redef fun visit(node)
	do
		if first == null then first = node

		if current_flow_context.node == null then current_flow_context.node = node
		node.accept_flow_visitor(self)
		if node isa AExpr then
			var flow = self.current_flow_context
			node.after_flow_context = flow
			# Force the creation of a specific merge after the analysis of the node.
			if flow.when_true != flow or flow.when_false != flow then
				self.make_sub_flow
				self.current_flow_context.name = "AUTOSUB"
			end
		end

		if first == node then
			#self.printflow
		end
	end
src/semantize/flow.nit:49,2--68,4

nitc $ ScopeVisitor :: visit
	redef fun visit(n)
	do
		n.accept_scope_visitor(self)
	end
src/semantize/scope.nit:127,2--130,4

nitc $ RapidTypeVisitor :: visit
	redef fun visit(n)
	do
		if n isa AExpr then
			if n.mtype != null or n.is_typed then
				n.accept_rapid_type_visitor(self)
				var implicit_cast_to = n.implicit_cast_to
				if implicit_cast_to != null then self.add_cast_type(implicit_cast_to)
			end
		else
			n.accept_rapid_type_visitor(self)
		end

		# RTA does not enter in AAnnotations
		if not n isa AAnnotations then
			n.visit_all(self)
		end
	end
src/rapid_type_analysis.nit:478,2--494,4

nitc $ SimpleMiscVisitor :: visit
	redef fun visit(n)
	do
		n.accept_simple_misc(self)
	end
src/frontend/simple_misc_analysis.nit:54,2--57,4

nitc $ DivByZeroVisitor :: visit
	redef fun visit(node)
	do
		# Recursively visit all sub-nodes
		node.visit_all(self)

		# Now just filter out until we get what we want...

		# 1. We need a `/` operation
		if not node isa ASlashExpr then return

		# 2. The second operand must be an integer literal
		var op2 = node.n_expr2
		if not op2 isa AIntegerExpr then return

		# 3. Its value must be 0
		# Note: because of `literal_phase` the `value` method exists
		if op2.value != 0 then return

		# 4. The receiver (first operand) must be an Int
		var op1 = node.n_expr
		var int_type = mmodule.get_primitive_class("Int").mclass_type
		if not op1.mtype.is_subtype(mmodule, null, int_type) then return

		# Error detected
		toolcontext.warning(node.location, "div-by-zero", "Warning: division by zero.")
	end
src/frontend/div_by_zero.nit:59,2--84,4

nitc $ ASTValidationVisitor :: visit
	redef fun visit(node)
	do
		node.accept_ast_validation(self)
	end
src/astbuilder.nit:860,2--863,4

nitc $ StringFinder :: visit
	redef fun visit(n)
	do
		n.accept_string_finder(self)
		n.visit_all(self)
	end
src/frontend/i18n_phase.nit:101,2--105,4

nitc $ RegexVisitor :: visit
	redef fun visit(n) do n.accept_regex_visitor(self)
src/frontend/regex_phase.nit:43,2--51

nitc $ ExplainAssertVisitor :: visit
	redef fun visit(node)
	do
		# Recursively visit all sub-nodes
		node.visit_all(self)

		# Only work on asserts
		if not node isa AAssertExpr then return
		var expr = node.n_expr

		# Skip assert on a single boolean var and asserts on false:
		# ~~~
		# assert false
		# # or
		# var x = false # Or any boolean expression
		# assert x
		# ~~~
		if expr isa AVarExpr or expr isa AFalseExpr then return

		# Build the superstring to explain the assert
		var explain_str = new ASuperstringExpr

		# Prepare attribute used by visited nodes
		self.assert_node = node
		self.explain_str = explain_str
		expr.accept_explain_assert self

		# Done! Store the superstring in the assert's node
		if explain_str.n_exprs.not_empty then
			node.explain_assert_str = explain_str
		end
	end
src/frontend/explain_assert.nit:81,2--111,4

nitc $ ContractsVisitor :: visit
	redef fun visit(node)
	do
		node.create_contracts(self)
		node.visit_all(self)
	end
src/contracts.nit:109,2--113,4

nitc $ CallSiteVisitor :: visit
	redef fun visit(node)
	do
		node.check_callsite(self)
		node.visit_all(self)
	end
src/contracts.nit:259,2--263,4

nitc $ TransformVisitor :: visit
	redef fun visit(node)
	do
		if node isa AAnnotations then return
		node.full_transform_visitor(self)
	end
src/transform.nit:70,2--74,4

nitc $ PTokenVisitor :: visit
	redef fun visit(n)
	do
		if not n isa Token then
			assert n isa Prod
			stack.push(n)
			n.visit_all(self)
			if n.first_token == null then
				# epsilon production, just discard
				assert stack.pop == n
			else
				var t = last_token
				if t != null then
					# last token ends the production
					n.last_token = t
					if t.ending_prods == null then t.ending_prods = new Array[Prod]
					t.ending_prods.add n
				end
			end
			return
		end

		# We have a token, give it to prods that need one
		if not stack.is_empty then
			n.starting_prods = new Array[Prod]
			for p in stack do
				p.first_token = n
				n.starting_prods.add p
			end
			stack.clear
		end

		var last_token = last_token

		# n starts a new line
		if last_token == null or last_token.location.line_start != n.location.line_start then
			n.is_starting_line = true
			n.first_real_token_in_line.first_ast_token = n

		end
		# last_token ended a line
		if last_token != null and last_token.location.line_start != n.location.line_start then
			last_token.is_ending_line = true
			last_token.last_real_token_in_line.last_ast_token = last_token
		end

		# Get the common parent
		var p
		if last_token == null then
			p = n.root
		else
			p = last_token.common_parent(n)
		end
		if p isa Prod then
			# And apply it to detached tokens between `last_token` and `n`
			var c = n.prev_token
			while c != null and c.parent == null do
				c.parent = p
				c = c.prev_token
			end
		end

		self.last_token = n
	end
src/astutil.nit:229,2--291,4

nitc $ TypeInitVisitor :: visit
	redef fun visit(node)
	do
		node.visit_all(self)
		# look for init
		if not node isa ANewExpr then return
		var mtype = node.n_type.mtype

		if mtype == null then return
		if mtype isa MNullableType then mtype = mtype.mtype
		if not mtype isa MClassType then return
		if mtype.mclass != mclass then return

		called = true
	end
src/doc/commands/commands_usage.nit:175,2--188,4

nitc $ MPropertyCallVisitor :: visit
	redef fun visit(node)
	do
		node.visit_all(self)
		if not node isa ASendExpr then return
		calls.add node.callsite.as(not null).mproperty
	end
src/doc/commands/commands_usage.nit:198,2--203,4

nitc $ ATypeCounterVisitor :: visit
	redef fun visit(n)
	do
		if n isa AAnnotation then return

		if n isa AType then do
			var mclassdef = self.nclassdef.mclassdef
			if mclassdef == null then break
			var mtype = modelbuilder.resolve_mtype(mclassdef, n)
			if mtype != null then
				self.typecount.inc(mtype)
			end
		end
		n.visit_all(self)
	end
src/metrics/static_types_metrics.nit:44,2--57,4

nitc $ NullableSends :: visit
	redef fun visit(n)
	do
		n.visit_all(self)
		if n isa ASendExpr then
			self.total_sends += 1
			var t = n.n_expr.mtype
			if t == null then
				self.buggy_sends += 1
				return
			end
			t = t.anchor_to(self.nclassdef.mclassdef.mmodule, self.nclassdef.mclassdef.bound_mtype)
			if t isa MNullableType then
				var p = n.callsite.mproperty
				if p.is_null_safe then
					self.nullable_eq_sends += 1
				else
					self.nullable_sends += 1
				end
			else if t isa MClassType then
				# Nothing
			else
				n.debug("Problem: strange receiver type found: {t} ({t.class_name})")
			end
		end
	end
src/metrics/nullables_metrics.nit:118,2--142,4

nitc $ ASelfVisitor :: visit
	redef fun visit(n)
	do
		if n isa ASelfExpr then
			self.total += 1
			if n isa AImplicitSelfExpr then
				self.implicits += 1
			end
		end
		n.visit_all(self)
	end
src/metrics/self_metrics.nit:40,2--49,4

nitc $ AstMetricsVisitor :: visit
	redef fun visit(n)
	do
		n.visit_all(self)
		phase.node_counter.inc(n.class_name)
		if n isa TId or n isa TAttrid or n isa TClassid then
			assert n isa Token
			phase.id_counter.inc(n.text)
		end
	end
src/metrics/ast_metrics.nit:53,2--61,4

nitc $ MethodAnalyzeMetrics :: visit
	redef fun visit(n) do
		n.visit_all(self)
		if n isa AExpr then
			if not n isa ABlockExpr then
				if n.first_location != null then
					line_number.inc(n.first_location.line_start)
				end
			end
		end
		if n isa ASendExpr then
			var callsite = n.callsite
			if callsite != null then
				var class_site_recv = callsite.recv
				if class_site_recv isa MClassType then class_call.inc(class_site_recv)
				if callsite.recv_is_self then self.total_self_call += 1
			end
		end
	end
src/metrics/method_analyze_metrics.nit:55,2--72,4

nitc $ CloneVisitor :: visit
	redef fun visit(node)
	do
		# return when the node is an annotation to avoid the clonage
		if node isa AAnnotations then return
		node.do_cloneable(self)
		node.visit_all(self)
	end
src/test_astbuilder.nit:39,2--45,4

nitc $ ForwardAnalysis :: visit
	redef fun visit(n) do n.accept_forward_analysis(self)
src/saf/saf_base.nit:89,2--54

nitc $ ReachingDefsAnalysis :: visit
	redef fun visit(n) do n.accept_reaching_defs(self)
src/saf/reaching_defs.nit:45,2--51

nitc $ ASTDump :: visit
	redef fun visit(n)
	do
		if not display_structural and n.is_structural then return
		var p = last_parent
		add(p, n)
		last_parent = n
		n.visit_all(self)
		last_parent = p
	end
src/parser/parser_nodes.nit:207,2--215,4