Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: pkg/servicec/lib/cycle_detection.dart

Issue 2035023003: Remove service-compiler related code. (Closed) Base URL: git@github.com:dartino/sdk.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/servicec/lib/converter.dart ('k') | pkg/servicec/lib/error_handling_listener.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library servicec.cycle_detection;
6
7 import 'dart:collection' show
8 LinkedHashSet;
9
10 import 'node.dart' show
11 MemberNode,
12 FieldNode,
13 SimpleType,
14 StructNode,
15 TypeNode,
16 UnionNode;
17
18 import 'errors.dart' show
19 CompilationError,
20 CyclicStructError,
21 ErrorTag;
22
23 class GraphNode {
24 GraphNodeState state = GraphNodeState.UNVISITED;
25 StructNode struct;
26
27 GraphNode(this.struct);
28
29 bool get isNotVisited => GraphNodeState.UNVISITED == state;
30
31 bool operator ==(GraphNode other) {
32 return struct == other.struct;
33 }
34 int get hashCode => struct.hashCode;
35
36 String toString() => "Node[${struct.identifier.value}, ${state.toString()}]";
37 }
38
39 enum GraphNodeState {
40 VISITED,
41 VISITING,
42 UNVISITED
43 }
44
45 class StructGraph {
46 Set<GraphNode> nodes;
47 Map<GraphNode, Set<GraphNode>> neighbours;
48
49 StructGraph()
50 : nodes = new LinkedHashSet<GraphNode>(), // Maintain node order.
51 neighbours = new Map<GraphNode, Set<GraphNode>>();
52
53 void add(StructNode struct) {
54 for (MemberNode member in struct.members) {
55 if (member is FieldNode) {
56 addStructField(struct, member);
57 } else {
58 UnionNode union = member;
59 union.fields.forEach((field) => addStructField(struct, field));
60 }
61 }
62 }
63
64 // Helper function.
65 void addStructField(StructNode struct, FieldNode field) {
66 TypeNode type = field.type;
67 if (type != null && type.isStruct()) {
68 SimpleType simpleType = type;
69 addLink(struct, simpleType.resolved);
70 }
71 }
72
73 void addLink(StructNode from, StructNode to) {
74 GraphNode fromNode = addNodeIfNew(from);
75 GraphNode toNode = addNodeIfNew(to);
76 neighbours[fromNode].add(toNode);
77 }
78
79 GraphNode addNodeIfNew(StructNode node) {
80 GraphNode result = nodes.firstWhere(
81 (graphNode) => graphNode.struct == node,
82 orElse: () => null);
83 if (null == result) {
84 result = new GraphNode(node);
85 nodes.add(result);
86 neighbours[result] = new Set<GraphNode>();
87 }
88 return result;
89 }
90
91 List<CompilationError> findCycles() {
92 List<CompilationError> errors = <CompilationError>[];
93 List<GraphNode> stack = new List<GraphNode>();
94 stack.addAll(nodes.toList().reversed.toList());
95 while (stack.isNotEmpty) {
96 GraphNode node = stack.last;
97 switch (node.state) {
98 case GraphNodeState.UNVISITED:
99 node.state = GraphNodeState.VISITING;
100 for (GraphNode neighbour in neighbours[node]) {
101 switch (neighbour.state) {
102 case GraphNodeState.UNVISITED:
103 // The `neighbour` hasn't been seen yet - add to stack.
104 stack.add(neighbour);
105 break;
106 case GraphNodeState.VISITING:
107 // The `neighbour` is in the current route from the root to the
108 // `node` - there is a cycle.
109 errors.add(createError(neighbour.struct, stack));
110 break;
111 case GraphNodeState.VISITED:
112 // The `neighbour` has already been searched - ignore.
113 break;
114 }
115 }
116 break;
117 case GraphNodeState.VISITING:
118 node.state = GraphNodeState.VISITED;
119 stack.removeLast();
120 break;
121 case GraphNodeState.VISITED:
122 // In this case the graph is a DAG.
123 stack.removeLast();
124 break;
125 }
126 }
127 return errors;
128 }
129
130 CyclicStructError createError(StructNode struct, List<GraphNode> stack) {
131 LinkedHashSet<StructNode> reversedChain = new LinkedHashSet<StructNode>();
132 reversedChain.add(struct);
133 for (int i = stack.length - 1; i >= 0; --i) {
134 if (stack[i].state == GraphNodeState.VISITING) {
135 reversedChain.add(stack[i].struct);
136 }
137 if (stack[i].struct == struct) break;
138 }
139
140 return new CyclicStructError(reversedChain.toList().reversed);
141 }
142 }
OLDNEW
« no previous file with comments | « pkg/servicec/lib/converter.dart ('k') | pkg/servicec/lib/error_handling_listener.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698