-
Notifications
You must be signed in to change notification settings - Fork 228
Expand file tree
/
Copy pathNType.java
More file actions
203 lines (165 loc) · 5.18 KB
/
NType.java
File metadata and controls
203 lines (165 loc) · 5.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/**
* Copyright 2009, Google Inc. All rights reserved.
* Licensed to PSF under a Contributor Agreement.
*/
package org.python.indexer.types;
import org.python.indexer.Builtins;
import org.python.indexer.Indexer;
import org.python.indexer.Scope;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class NType {
private Scope table;
protected static final String LIBRARY_URL = Builtins.LIBRARY_URL;
protected static final String TUTORIAL_URL = Builtins.TUTORIAL_URL;
protected static final String REFERENCE_URL = Builtins.REFERENCE_URL;
private static Pattern INSTANCE_TAG = Pattern.compile("(.+?)=#([0-9]+)");
public NType() {
}
public void setTable(Scope table) {
this.table = table;
}
public Scope getTable() {
if (table == null) {
table = new Scope(null, Scope.Type.SCOPE);
}
return table;
}
/**
* Returns {@link NUnknownType#follow} of this type.
*/
public NType follow() {
return NUnknownType.follow(this);
}
/**
* Returns {@code true} if this Python type is implemented in native code
* (i.e., C, Java, C# or some other host language.)
*/
public boolean isNative() {
return Indexer.idx.builtins.isNative(this);
}
public boolean isClassType() {
return this instanceof NClassType;
}
public boolean isDictType() {
return this instanceof NDictType;
}
public boolean isFuncType() {
return this instanceof NFuncType;
}
public boolean isInstanceType() {
return this instanceof NInstanceType;
}
public boolean isListType() {
return this instanceof NListType;
}
public boolean isModuleType() {
return this instanceof NModuleType;
}
public boolean isNumType() {
return this == Indexer.idx.builtins.BaseNum;
}
public boolean isStrType() {
return this == Indexer.idx.builtins.BaseStr;
}
public boolean isTupleType() {
return this instanceof NTupleType;
}
public boolean isUnionType() {
return this instanceof NUnionType;
}
public boolean isUnknownType() {
return this instanceof NUnknownType;
}
public NClassType asClassType() {
return (NClassType)this;
}
public NDictType asDictType() {
return (NDictType)this;
}
public NFuncType asFuncType() {
return (NFuncType)this;
}
public NInstanceType asInstanceType() {
return (NInstanceType)this;
}
public NListType asListType() {
return (NListType)this;
}
public NModuleType asModuleType() {
return (NModuleType)this;
}
public NTupleType asTupleType() {
return (NTupleType)this;
}
public NUnionType asUnionType() {
return (NUnionType)this;
}
public NUnknownType asUnknownType() {
return (NUnknownType)this;
}
@Override
public String toString() {
StringBuilder input = new StringBuilder();
print(new CyclicTypeRecorder(), input);
// Postprocess to remove unused instance reference numbers.
StringBuilder sb = new StringBuilder(input.length());
Matcher m = INSTANCE_TAG.matcher(input.toString());
int end = -1;
while (m.find()) {
end = m.end();
int num = Integer.parseInt(m.group(2));
if (input.indexOf("<#" + num + ">") == -1) { // referenced?
sb.append(m.group(1)); // skip tag
} else {
sb.append(m.group()); // whole thing
}
}
if (end != -1) {
sb.append(input.substring(end));
}
return sb.toString();
}
/**
* Internal class to support printing in the presence of type-graph cycles.
*/
protected class CyclicTypeRecorder {
int count = 0;
private Map<NType, Integer> elements = new HashMap<NType, Integer>();
/**
* Get the instance number for the specified type.
* @return the instance number: positive if the type was already recorded,
* or its negative if the type was just recorded and assigned a number.
*/
public int fetch(NType t) {
Integer i = elements.get(t);
if (i != null) {
return i;
}
i = ++count;
elements.put(t, i);
return -i;
}
}
/**
* Internal method to support printing in the presence of type-graph cycles.
*/
protected void print(CyclicTypeRecorder ctr, StringBuilder sb) {
int num = ctr.fetch(this);
if (num > 0) {
sb.append("<#").append(num).append(">");
} else {
String tag = getClass().getName();
tag = tag.substring(tag.lastIndexOf(".") + 2);
sb.append("<").append(tag).append("=#").append(-num).append(":");
printKids(ctr, sb);
sb.append(">");
}
}
/**
* Internal method to support printing in the presence of type-graph cycles.
*/
protected abstract void printKids(CyclicTypeRecorder ctr, StringBuilder sb);
}