use of com.android.annotations.Nullable in project kotlin by JetBrains.
the class TypoLookup method get.
/**
* Returns an instance of the typo database
*
* @param client the client to associate with this database - used only for
* logging
* @param xmlFile the XML file containing configuration data to use for this
* database
* @return a (possibly shared) instance of the typo database, or null
* if its data can't be found
*/
@Nullable
private static TypoLookup get(LintClient client, File xmlFile) {
if (!xmlFile.exists()) {
client.log(null, "The typo database file %1$s does not exist", xmlFile);
return null;
}
String name = xmlFile.getName();
if (LintUtils.endsWith(name, DOT_XML)) {
name = name.substring(0, name.length() - DOT_XML.length());
}
File cacheDir = client.getCacheDir(true);
if (cacheDir == null) {
cacheDir = xmlFile.getParentFile();
}
File binaryData = new File(cacheDir, name + // conflicts on Windows (such as issue #26663)
'-' + BINARY_FORMAT_VERSION + //$NON-NLS-1$
".bin");
if (DEBUG_FORCE_REGENERATE_BINARY) {
System.err.println("\nTemporarily regenerating binary data unconditionally \nfrom " + xmlFile + "\nto " + binaryData);
if (!createCache(client, xmlFile, binaryData)) {
return null;
}
} else if (!binaryData.exists() || binaryData.lastModified() < xmlFile.lastModified()) {
if (!createCache(client, xmlFile, binaryData)) {
return null;
}
}
if (!binaryData.exists()) {
client.log(null, "The typo database file %1$s does not exist", binaryData);
return null;
}
return new TypoLookup(client, xmlFile, binaryData);
}
use of com.android.annotations.Nullable in project android by JetBrains.
the class MissingAndroidSdkErrorHandler method findErrorMessage.
@Override
@Nullable
protected String findErrorMessage(@NotNull Throwable rootCause, @NotNull NotificationData notification, @NotNull Project project) {
String text = rootCause.getMessage();
if (rootCause instanceof RuntimeException && isNotEmpty(text) && (text.equals(SDK_DIR_PROPERTY_MISSING) || SDK_NOT_FOUND_PATTERN.matcher(text).matches())) {
updateUsageTracker(SDK_NOT_FOUND);
File buildProperties = new File(getBaseDirPath(project), FN_LOCAL_PROPERTIES);
if (buildProperties.isFile()) {
text += EMPTY_LINE + FIX_SDK_DIR_PROPERTY;
return text;
}
}
return null;
}
use of com.android.annotations.Nullable in project buck by facebook.
the class PositionXmlParser method findNodeAtOffset.
@Nullable
private static Node findNodeAtOffset(@NonNull Node node, int offset) {
Position p = getPositionHelper(node, -1, -1);
if (p != null) {
if (offset < p.getOffset()) {
return null;
}
Position end = p.getEnd();
if (end != null) {
if (offset >= end.getOffset()) {
return null;
}
}
} else {
return null;
}
NodeList children = node.getChildNodes();
for (int i = 0, n = children.getLength(); i < n; i++) {
Node item = children.item(i);
Node match = findNodeAtOffset(item, offset);
if (match != null) {
return match;
}
}
NamedNodeMap attributes = node.getAttributes();
if (attributes != null) {
for (int i = 0, n = attributes.getLength(); i < n; i++) {
Node item = attributes.item(i);
Node match = findNodeAtOffset(item, offset);
if (match != null) {
return match;
}
}
}
return node;
}
use of com.android.annotations.Nullable in project buck by facebook.
the class PositionXmlParser method getPositionHelper.
@Nullable
private static Position getPositionHelper(@NonNull Node node, int start, int end) {
// and if found uses that as the exact node offsets instead.
if (node instanceof Attr) {
Attr attr = (Attr) node;
Position pos = (Position) attr.getOwnerElement().getUserData(POS_KEY);
if (pos != null) {
int startOffset = pos.getOffset();
int endOffset = pos.getEnd().getOffset();
if (start != -1) {
startOffset += start;
if (end != -1) {
endOffset = startOffset + (end - start);
}
}
// Find attribute in the text
String contents = (String) node.getOwnerDocument().getUserData(CONTENT_KEY);
if (contents == null) {
return null;
}
// Locate the name=value attribute in the source text
// Fast string check first for the common occurrence
String name = attr.getName();
Pattern pattern = Pattern.compile(attr.getPrefix() != null ? //$NON-NLS-1$
String.format("(%1$s\\s*=\\s*[\"'].*?[\"'])", name) : //$NON-NLS-1$
String.format("[^:](%1$s\\s*=\\s*[\"'].*?[\"'])", name));
Matcher matcher = pattern.matcher(contents);
if (matcher.find(startOffset) && matcher.start(1) <= endOffset) {
int index = matcher.start(1);
// Adjust the line and column to this new offset
int line = pos.getLine();
int column = pos.getColumn();
for (int offset = pos.getOffset(); offset < index; offset++) {
char t = contents.charAt(offset);
if (t == '\n') {
line++;
column = 0;
} else {
column++;
}
}
Position attributePosition = new Position(line, column, index);
// Also set end range for retrieval in getLocation
attributePosition.setEnd(new Position(line, column + matcher.end(1) - index, matcher.end(1)));
return attributePosition;
} else {
// No regexp match either: just fall back to element position
return pos;
}
}
} else if (node instanceof Text) {
// Position of parent element, if any
Position pos = null;
if (node.getPreviousSibling() != null) {
pos = (Position) node.getPreviousSibling().getUserData(POS_KEY);
}
if (pos == null) {
pos = (Position) node.getParentNode().getUserData(POS_KEY);
}
if (pos != null) {
// Attempt to point forward to the actual text node
int startOffset = pos.getOffset();
int endOffset = pos.getEnd().getOffset();
int line = pos.getLine();
int column = pos.getColumn();
// Find attribute in the text
String contents = (String) node.getOwnerDocument().getUserData(CONTENT_KEY);
if (contents == null || contents.length() < endOffset) {
return null;
}
boolean inAttribute = false;
for (int offset = startOffset; offset <= endOffset; offset++) {
char c = contents.charAt(offset);
if (c == '>' && !inAttribute) {
// Found the end of the element open tag: this is where the
// text begins.
// Skip >
offset++;
column++;
String text = node.getNodeValue();
int textIndex = 0;
int textLength = text.length();
int newLine = line;
int newColumn = column;
if (start != -1) {
textLength = Math.min(textLength, start);
for (; textIndex < textLength; textIndex++) {
char t = text.charAt(textIndex);
if (t == '\n') {
newLine++;
newColumn = 0;
} else {
newColumn++;
}
}
} else {
// non-whitespace characters
for (; textIndex < textLength; textIndex++) {
char t = text.charAt(textIndex);
if (t == '\n') {
newLine++;
newColumn = 0;
} else if (!Character.isWhitespace(t)) {
break;
} else {
newColumn++;
}
}
}
if (textIndex == text.length()) {
// Whitespace node
textIndex = 0;
} else {
line = newLine;
column = newColumn;
}
Position attributePosition = new Position(line, column, offset + textIndex);
// Also set end range for retrieval in getLocation
if (end != -1) {
attributePosition.setEnd(new Position(line, column, offset + end));
} else {
attributePosition.setEnd(new Position(line, column, offset + textLength));
}
return attributePosition;
} else if (c == '"') {
inAttribute = !inAttribute;
} else if (c == '\n') {
line++;
// pre-subtract column added below
column = -1;
}
column++;
}
return pos;
}
}
return (Position) node.getUserData(POS_KEY);
}
use of com.android.annotations.Nullable in project bazel by bazelbuild.
the class AndroidResourceProcessor method loadResourceSymbolTable.
@Nullable
public SymbolLoader loadResourceSymbolTable(List<SymbolFileProvider> libraries, String appPackageName, Path primaryRTxt, Multimap<String, SymbolLoader> libMap) throws IOException {
// The reported availableProcessors may be higher than the actual resources
// (on a shared system). On the other hand, a lot of the work is I/O, so it's not completely
// CPU bound. As a compromise, divide by 2 the reported availableProcessors.
int numThreads = Math.max(1, Runtime.getRuntime().availableProcessors() / 2);
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(numThreads));
try (Closeable closeable = ExecutorServiceCloser.createWith(executorService)) {
// Load the package names from the manifest files.
Map<SymbolFileProvider, ListenableFuture<String>> packageJobs = new HashMap<>();
for (final SymbolFileProvider lib : libraries) {
packageJobs.put(lib, executorService.submit(new PackageParsingTask(lib.getManifest())));
}
Map<SymbolFileProvider, String> packageNames = new HashMap<>();
try {
for (Map.Entry<SymbolFileProvider, ListenableFuture<String>> entry : packageJobs.entrySet()) {
packageNames.put(entry.getKey(), entry.getValue().get());
}
} catch (InterruptedException | ExecutionException e) {
throw new IOException("Failed to load package name: ", e);
}
// Associate the packages with symbol files.
for (SymbolFileProvider lib : libraries) {
String packageName = packageNames.get(lib);
// stored in the primaryRTxt file.
if (appPackageName.equals(packageName)) {
continue;
}
File rFile = lib.getSymbolFile();
// If the library has no resource, this file won't exist.
if (rFile.isFile()) {
SymbolLoader libSymbols = new SymbolLoader(rFile, stdLogger);
libMap.put(packageName, libSymbols);
}
}
// Even if there are no libraries, load fullSymbolValues, in case we only have resources
// defined for the binary.
File primaryRTxtFile = primaryRTxt.toFile();
SymbolLoader fullSymbolValues = null;
if (primaryRTxtFile.isFile()) {
fullSymbolValues = new SymbolLoader(primaryRTxtFile, stdLogger);
}
// Now load the symbol files in parallel.
List<ListenableFuture<?>> loadJobs = new ArrayList<>();
Iterable<SymbolLoader> toLoad = fullSymbolValues != null ? Iterables.concat(libMap.values(), ImmutableList.of(fullSymbolValues)) : libMap.values();
for (final SymbolLoader loader : toLoad) {
loadJobs.add(executorService.submit(new SymbolLoadingTask(loader)));
}
try {
Futures.allAsList(loadJobs).get();
} catch (InterruptedException | ExecutionException e) {
throw new IOException("Failed to load SymbolFile: ", e);
}
return fullSymbolValues;
}
}
Aggregations