IDEA-90182 do not resolve/complete private system xml attributes

This commit is contained in:
Eugene Kudelevsky
2012-08-24 22:55:47 +04:00
parent 77ba6b8590
commit fd6044b133
16 changed files with 474 additions and 300 deletions
@@ -180,9 +180,7 @@ public class PropertyParser {
"paddingLeft", "left",
"paddingTop", "top",
"paddingRight", "right",
"paddingBottom", "bottom",
"paddingStart", "start",
"paddingEnd", "end");
"paddingBottom", "bottom");
if (model != null) {
paddingProperty.decorate(model);
}
@@ -1,247 +1,23 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.android.dom.attrs;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlComment;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.containers.HashMap;
import com.intellij.xml.util.XmlUtil;
import com.intellij.xml.util.documentation.XmlDocumentationProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Set;
/**
* @author yole
* @author Eugene.Kudelevsky
*/
public class AttributeDefinitions {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.dom.attrs.AttributeDefinitions");
private Map<String, AttributeDefinition> myAttrs = new HashMap<String, AttributeDefinition>();
private Map<String, StyleableDefinition> myStyleables = new HashMap<String, StyleableDefinition>();
private final List<StyleableDefinition> myStateStyleables = new ArrayList<StyleableDefinition>();
private final Map<String, Map<String, Integer>> myEnumMap = new HashMap<String, Map<String, Integer>>();
public AttributeDefinitions() {
}
public AttributeDefinitions(@NotNull XmlFile... files) {
for (XmlFile file : files) {
addAttrsFromFile(file);
}
}
private void addAttrsFromFile(XmlFile file) {
Map<StyleableDefinition, String[]> parentMap = new HashMap<StyleableDefinition, String[]>();
final XmlDocument document = file.getDocument();
if (document == null) return;
final XmlTag rootTag = document.getRootTag();
if (rootTag == null || !"resources".equals(rootTag.getName())) return;
for (XmlTag tag : rootTag.getSubTags()) {
String tagName = tag.getName();
if (tagName.equals("attr")) {
parseAttrTag(tag);
}
else if (tagName.equals("declare-styleable")) {
parseDeclareStyleableTag(tag, parentMap);
}
}
for (Map.Entry<StyleableDefinition, String[]> entry : parentMap.entrySet()) {
StyleableDefinition definition = entry.getKey();
String[] parentNames = entry.getValue();
for (String parentName : parentNames) {
StyleableDefinition parent = getStyleableByName(parentName);
if (parent != null) {
definition.addParent(parent);
parent.addChild(definition);
}
else {
LOG.info("Found tag with unknown parent: " + parentName);
}
}
}
}
public interface AttributeDefinitions {
@Nullable
private AttributeDefinition parseAttrTag(XmlTag tag) {
String name = tag.getAttributeValue("name");
if (name == null) {
LOG.info("Found attr tag with no name: " + tag.getText());
return null;
}
List<AttributeFormat> parsedFormats;
List<AttributeFormat> formats = new ArrayList<AttributeFormat>();
String format = tag.getAttributeValue("format");
if (format != null) {
parsedFormats = parseAttrFormat(format);
if (parsedFormats != null) formats.addAll(parsedFormats);
}
XmlTag[] values = tag.findSubTags("enum");
if (values.length > 0) {
formats.add(AttributeFormat.Enum);
}
else {
values = tag.findSubTags("flag");
if (values.length > 0) {
formats.add(AttributeFormat.Flag);
}
}
AttributeDefinition def = myAttrs.get(name);
if (def == null) {
def = new AttributeDefinition(name);
myAttrs.put(def.getName(), def);
}
def.addFormats(formats);
parseDocComment(tag, def);
parseAndAddValues(def, values);
return def;
}
private static void parseDocComment(XmlTag tag, AttributeDefinition def) {
PsiElement comment = XmlDocumentationProvider.findPreviousComment(tag);
if (comment != null) {
String docValue = XmlUtil.getCommentText((XmlComment)comment);
if (!StringUtil.isEmpty(docValue)) {
def.addDocValue(docValue);
}
}
}
private static List<AttributeFormat> parseAttrFormat(String formatString) {
List<AttributeFormat> result = new ArrayList<AttributeFormat>();
final String[] formats = formatString.split("\\|");
for (String format : formats) {
final AttributeFormat attributeFormat;
try {
attributeFormat = AttributeFormat.valueOf(StringUtil.capitalize(format));
}
catch (IllegalArgumentException e) {
return null;
}
result.add(attributeFormat);
}
return result;
}
private void parseAndAddValues(AttributeDefinition def, XmlTag[] values) {
for (XmlTag value : values) {
final String valueName = value.getAttributeValue("name");
if (valueName == null) {
LOG.info("Unknown value for tag: " + value.getText());
}
else {
def.addValue(valueName);
final String strIntValue = value.getAttributeValue("value");
if (strIntValue != null) {
try {
int intValue = strIntValue.startsWith("0x")
? Integer.parseInt(strIntValue.substring(2), 16)
: Integer.parseInt(strIntValue);
Map<String, Integer> value2Int = myEnumMap.get(def.getName());
if (value2Int == null) {
value2Int = new HashMap<String, Integer>();
myEnumMap.put(def.getName(), value2Int);
}
value2Int.put(valueName, intValue);
}
catch (NumberFormatException ignored) {
}
}
}
}
}
private void parseDeclareStyleableTag(XmlTag tag, Map<StyleableDefinition, String[]> parentMap) {
String name = tag.getAttributeValue("name");
if (name == null) {
LOG.info("Found declare-styleable tag with no name: " + tag.getText());
return;
}
StyleableDefinition def = new StyleableDefinition(name);
String parentNameAttributeValue = tag.getAttributeValue("parent");
if (parentNameAttributeValue != null) {
String[] parentNames = parentNameAttributeValue.split("\\s+");
parentMap.put(def, parentNames);
}
myStyleables.put(name, def);
if (name.endsWith("State")) {
myStateStyleables.add(def);
}
for (XmlTag subTag : tag.findSubTags("attr")) {
parseStyleableAttr(def, subTag);
}
}
private void parseStyleableAttr(StyleableDefinition def, XmlTag tag) {
String name = tag.getAttributeValue("name");
if (name == null) {
LOG.info("Found attr tag with no name: " + tag.getText());
return;
}
final AttributeDefinition attr = parseAttrTag(tag);
if (attr != null) {
def.addAttribute(attr);
}
}
public void addStyleable(@NotNull StyleableDefinition styleable) {
myStyleables.put(styleable.getName(), styleable);
}
public void addAttrDef(@NotNull AttributeDefinition attr) {
myAttrs.put(attr.getName(), attr);
}
@Nullable
public StyleableDefinition getStyleableByName(@NotNull String name) {
return myStyleables.get(name);
}
public Set<String> getAttributeNames() {
return myAttrs.keySet();
}
@Nullable
public AttributeDefinition getAttrDefByName(@NotNull String name) {
return myAttrs.get(name);
}
StyleableDefinition getStyleableByName(@NotNull String name);
@NotNull
public Set<String> getStyleableNames() {
return myStyleables.keySet();
}
Set<String> getAttributeNames();
public StyleableDefinition[] getStateStyleables() {
return myStateStyleables.toArray(new StyleableDefinition[myStateStyleables.size()]);
}
@Nullable
AttributeDefinition getAttrDefByName(@NotNull String name);
@NotNull
public Map<String, Map<String, Integer>> getEnumMap() {
return myEnumMap;
}
StyleableDefinition[] getStateStyleables();
}
@@ -0,0 +1,237 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.android.dom.attrs;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlComment;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.containers.HashMap;
import com.intellij.xml.util.XmlUtil;
import com.intellij.xml.util.documentation.XmlDocumentationProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* @author yole
*/
public class AttributeDefinitionsImpl implements AttributeDefinitions {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.android.dom.attrs.AttributeDefinitionsImpl");
private Map<String, AttributeDefinition> myAttrs = new HashMap<String, AttributeDefinition>();
private Map<String, StyleableDefinitionImpl> myStyleables = new HashMap<String, StyleableDefinitionImpl>();
private final List<StyleableDefinition> myStateStyleables = new ArrayList<StyleableDefinition>();
private final Map<String, Map<String, Integer>> myEnumMap = new HashMap<String, Map<String, Integer>>();
public AttributeDefinitionsImpl(@NotNull XmlFile... files) {
for (XmlFile file : files) {
addAttrsFromFile(file);
}
}
private void addAttrsFromFile(XmlFile file) {
Map<StyleableDefinitionImpl, String[]> parentMap = new HashMap<StyleableDefinitionImpl, String[]>();
final XmlDocument document = file.getDocument();
if (document == null) return;
final XmlTag rootTag = document.getRootTag();
if (rootTag == null || !"resources".equals(rootTag.getName())) return;
for (XmlTag tag : rootTag.getSubTags()) {
String tagName = tag.getName();
if (tagName.equals("attr")) {
parseAttrTag(tag);
}
else if (tagName.equals("declare-styleable")) {
parseDeclareStyleableTag(tag, parentMap);
}
}
for (Map.Entry<StyleableDefinitionImpl, String[]> entry : parentMap.entrySet()) {
StyleableDefinitionImpl definition = entry.getKey();
String[] parentNames = entry.getValue();
for (String parentName : parentNames) {
StyleableDefinitionImpl parent = getStyleableByName(parentName);
if (parent != null) {
definition.addParent(parent);
parent.addChild(definition);
}
else {
LOG.info("Found tag with unknown parent: " + parentName);
}
}
}
}
@Nullable
private AttributeDefinition parseAttrTag(XmlTag tag) {
String name = tag.getAttributeValue("name");
if (name == null) {
LOG.info("Found attr tag with no name: " + tag.getText());
return null;
}
List<AttributeFormat> parsedFormats;
List<AttributeFormat> formats = new ArrayList<AttributeFormat>();
String format = tag.getAttributeValue("format");
if (format != null) {
parsedFormats = parseAttrFormat(format);
if (parsedFormats != null) formats.addAll(parsedFormats);
}
XmlTag[] values = tag.findSubTags("enum");
if (values.length > 0) {
formats.add(AttributeFormat.Enum);
}
else {
values = tag.findSubTags("flag");
if (values.length > 0) {
formats.add(AttributeFormat.Flag);
}
}
AttributeDefinition def = myAttrs.get(name);
if (def == null) {
def = new AttributeDefinition(name);
myAttrs.put(def.getName(), def);
}
def.addFormats(formats);
parseDocComment(tag, def);
parseAndAddValues(def, values);
return def;
}
private static void parseDocComment(XmlTag tag, AttributeDefinition def) {
PsiElement comment = XmlDocumentationProvider.findPreviousComment(tag);
if (comment != null) {
String docValue = XmlUtil.getCommentText((XmlComment)comment);
if (!StringUtil.isEmpty(docValue)) {
def.addDocValue(docValue);
}
}
}
private static List<AttributeFormat> parseAttrFormat(String formatString) {
List<AttributeFormat> result = new ArrayList<AttributeFormat>();
final String[] formats = formatString.split("\\|");
for (String format : formats) {
final AttributeFormat attributeFormat;
try {
attributeFormat = AttributeFormat.valueOf(StringUtil.capitalize(format));
}
catch (IllegalArgumentException e) {
return null;
}
result.add(attributeFormat);
}
return result;
}
private void parseAndAddValues(AttributeDefinition def, XmlTag[] values) {
for (XmlTag value : values) {
final String valueName = value.getAttributeValue("name");
if (valueName == null) {
LOG.info("Unknown value for tag: " + value.getText());
}
else {
def.addValue(valueName);
final String strIntValue = value.getAttributeValue("value");
if (strIntValue != null) {
try {
int intValue = strIntValue.startsWith("0x")
? Integer.parseInt(strIntValue.substring(2), 16)
: Integer.parseInt(strIntValue);
Map<String, Integer> value2Int = myEnumMap.get(def.getName());
if (value2Int == null) {
value2Int = new HashMap<String, Integer>();
myEnumMap.put(def.getName(), value2Int);
}
value2Int.put(valueName, intValue);
}
catch (NumberFormatException ignored) {
}
}
}
}
}
private void parseDeclareStyleableTag(XmlTag tag, Map<StyleableDefinitionImpl, String[]> parentMap) {
String name = tag.getAttributeValue("name");
if (name == null) {
LOG.info("Found declare-styleable tag with no name: " + tag.getText());
return;
}
StyleableDefinitionImpl def = new StyleableDefinitionImpl(name);
String parentNameAttributeValue = tag.getAttributeValue("parent");
if (parentNameAttributeValue != null) {
String[] parentNames = parentNameAttributeValue.split("\\s+");
parentMap.put(def, parentNames);
}
myStyleables.put(name, def);
if (name.endsWith("State")) {
myStateStyleables.add(def);
}
for (XmlTag subTag : tag.findSubTags("attr")) {
parseStyleableAttr(def, subTag);
}
}
private void parseStyleableAttr(StyleableDefinitionImpl def, XmlTag tag) {
String name = tag.getAttributeValue("name");
if (name == null) {
LOG.info("Found attr tag with no name: " + tag.getText());
return;
}
final AttributeDefinition attr = parseAttrTag(tag);
if (attr != null) {
def.addAttribute(attr);
}
}
@Override
@Nullable
public StyleableDefinitionImpl getStyleableByName(@NotNull String name) {
return myStyleables.get(name);
}
@NotNull
@Override
public Set<String> getAttributeNames() {
return myAttrs.keySet();
}
@Override
@Nullable
public AttributeDefinition getAttrDefByName(@NotNull String name) {
return myAttrs.get(name);
}
@NotNull
@Override
public StyleableDefinition[] getStateStyleables() {
return myStateStyleables.toArray(new StyleableDefinition[myStateStyleables.size()]);
}
@NotNull
public Map<String, Map<String, Integer>> getEnumMap() {
return myEnumMap;
}
}
@@ -1,68 +1,20 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.android.dom.attrs;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author yole, coyote
* @author Eugene.Kudelevsky
*/
public class StyleableDefinition {
private final String myName;
private final List<StyleableDefinition> parents = new ArrayList<StyleableDefinition>();
private final List<AttributeDefinition> myAttributes = new ArrayList<AttributeDefinition>();
private final List<StyleableDefinition> children = new ArrayList<StyleableDefinition>();
public StyleableDefinition(@NotNull String name) {
myName = name;
}
public void addChild(@NotNull StyleableDefinition child) {
children.add(child);
}
public void addParent(@NotNull StyleableDefinition parent) {
parents.add(parent);
}
public interface StyleableDefinition {
@NotNull
public List<StyleableDefinition> getParents() {
return parents;
}
List<StyleableDefinition> getChildren();
@NotNull
public List<StyleableDefinition> getChildren() {
return children;
}
String getName();
@NotNull
public String getName() {
return myName;
}
public void addAttribute(@NotNull AttributeDefinition attrDef) {
myAttributes.add(attrDef);
}
@NotNull
public List<AttributeDefinition> getAttributes() {
return Collections.unmodifiableList(myAttributes);
}
List<AttributeDefinition> getAttributes();
}
@@ -0,0 +1,71 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.android.dom.attrs;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author yole, coyote
*/
public class StyleableDefinitionImpl implements StyleableDefinition {
private final String myName;
private final List<StyleableDefinition> myParents = new ArrayList<StyleableDefinition>();
private final List<AttributeDefinition> myAttributes = new ArrayList<AttributeDefinition>();
private final List<StyleableDefinition> myChildren = new ArrayList<StyleableDefinition>();
public StyleableDefinitionImpl(@NotNull String name) {
myName = name;
}
public void addChild(@NotNull StyleableDefinition child) {
myChildren.add(child);
}
public void addParent(@NotNull StyleableDefinition parent) {
myParents.add(parent);
}
@NotNull
public List<StyleableDefinition> getParents() {
return myParents;
}
@Override
@NotNull
public List<StyleableDefinition> getChildren() {
return myChildren;
}
@Override
@NotNull
public String getName() {
return myName;
}
public void addAttribute(@NotNull AttributeDefinition attrDef) {
myAttributes.add(attrDef);
}
@Override
@NotNull
public List<AttributeDefinition> getAttributes() {
return Collections.unmodifiableList(myAttributes);
}
}
@@ -0,0 +1,102 @@
package org.jetbrains.android.resourceManagers;
import com.intellij.util.containers.HashSet;
import org.jetbrains.android.dom.attrs.AttributeDefinition;
import org.jetbrains.android.dom.attrs.AttributeDefinitions;
import org.jetbrains.android.dom.attrs.StyleableDefinition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* @author Eugene.Kudelevsky
*/
public abstract class FilteredAttributeDefinitions implements AttributeDefinitions {
private final AttributeDefinitions myWrappee;
protected FilteredAttributeDefinitions(@NotNull AttributeDefinitions wrappee) {
myWrappee = wrappee;
}
protected abstract boolean isAttributeAcceptable(@NotNull String name);
@Nullable
@Override
public StyleableDefinition getStyleableByName(@NotNull String name) {
final StyleableDefinition styleable = myWrappee.getStyleableByName(name);
return styleable != null ? new MyStyleableDefinition(styleable) : null;
}
@NotNull
@Override
public Set<String> getAttributeNames() {
final Set<String> result = new HashSet<String>();
for (String name : myWrappee.getAttributeNames()) {
if (isAttributeAcceptable(name)) {
result.add(name);
}
}
return result;
}
@Nullable
@Override
public AttributeDefinition getAttrDefByName(@NotNull String name) {
return isAttributeAcceptable(name) ? myWrappee.getAttrDefByName(name) : null;
}
@NotNull
@Override
public StyleableDefinition[] getStateStyleables() {
final StyleableDefinition[] styleables = myWrappee.getStateStyleables();
final StyleableDefinition[] result = new StyleableDefinition[styleables.length];
for (int i = 0; i < styleables.length; i++) {
result[i] = new MyStyleableDefinition(styleables[i]);
}
return result;
}
private class MyStyleableDefinition implements StyleableDefinition {
private final StyleableDefinition myWrappee;
private MyStyleableDefinition(@NotNull StyleableDefinition wrappee) {
myWrappee = wrappee;
}
@NotNull
@Override
public List<StyleableDefinition> getChildren() {
final List<StyleableDefinition> styleables = myWrappee.getChildren();
final List<StyleableDefinition> result = new ArrayList<StyleableDefinition>(styleables.size());
for (StyleableDefinition styleable : styleables) {
result.add(new MyStyleableDefinition(styleable));
}
return result;
}
@NotNull
@Override
public String getName() {
return myWrappee.getName();
}
@NotNull
@Override
public List<AttributeDefinition> getAttributes() {
final List<AttributeDefinition> result = new ArrayList<AttributeDefinition>();
for (AttributeDefinition definition : myWrappee.getAttributes()) {
if (isAttributeAcceptable(definition.getName())) {
result.add(definition);
}
}
return result;
}
}
}
@@ -37,6 +37,7 @@ import com.intellij.util.indexing.FileBasedIndex;
import org.jetbrains.android.AndroidFileTemplateProvider;
import org.jetbrains.android.AndroidValueResourcesIndex;
import org.jetbrains.android.dom.attrs.AttributeDefinitions;
import org.jetbrains.android.dom.attrs.AttributeDefinitionsImpl;
import org.jetbrains.android.dom.resources.Attr;
import org.jetbrains.android.dom.resources.DeclareStyleable;
import org.jetbrains.android.dom.resources.ResourceElement;
@@ -181,7 +182,7 @@ public class LocalResourceManager extends ResourceManager {
xmlResFiles.add((XmlFile)file);
}
}
myAttrDefs = new AttributeDefinitions(xmlResFiles.toArray(new XmlFile[xmlResFiles.size()]));
myAttrDefs = new AttributeDefinitionsImpl(xmlResFiles.toArray(new XmlFile[xmlResFiles.size()]));
}
});
}
@@ -15,6 +15,7 @@
*/
package org.jetbrains.android.resourceManagers;
import com.android.resources.ResourceType;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.intellij.openapi.application.ApplicationManager;
@@ -117,6 +118,21 @@ public class SystemResourceManager extends ResourceManager {
@Nullable
public synchronized AttributeDefinitions getAttributeDefinitions() {
final AndroidTargetData targetData = myPlatform.getSdkData().getTargetData(myPlatform.getTarget());
return targetData != null ? targetData.getAttrDefs(myModule.getProject()) : null;
if (targetData == null) {
return null;
}
final AttributeDefinitions attrDefs = targetData.getAttrDefs(myModule.getProject());
return attrDefs != null ? new MyAttributeDefinitions(attrDefs) : null;
}
private class MyAttributeDefinitions extends FilteredAttributeDefinitions {
protected MyAttributeDefinitions(@NotNull AttributeDefinitions wrappee) {
super(wrappee);
}
@Override
protected boolean isAttributeAcceptable(@NotNull String name) {
return isResourcePublic(ResourceType.ATTR.getName(), name);
}
}
}
@@ -17,7 +17,7 @@ import com.intellij.psi.XmlRecursiveElementVisitor;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.containers.HashSet;
import org.jetbrains.android.dom.attrs.AttributeDefinitions;
import org.jetbrains.android.dom.attrs.AttributeDefinitionsImpl;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.resourceManagers.SystemResourceManager;
import org.jetbrains.android.uipreview.RenderServiceFactory;
@@ -37,7 +37,7 @@ public class AndroidTargetData {
private final AndroidSdkData mySdkData;
private final IAndroidTarget myTarget;
private volatile AttributeDefinitions myAttrDefs;
private volatile AttributeDefinitionsImpl myAttrDefs;
private volatile RenderServiceFactory myRenderServiceFactory;
private volatile Set<String> myThemes;
private volatile boolean myThemesLoaded;
@@ -48,7 +48,7 @@ public class AndroidTargetData {
}
@Nullable
public AttributeDefinitions getAttrDefs(@NotNull final Project project) {
public AttributeDefinitionsImpl getAttrDefs(@NotNull final Project project) {
if (myAttrDefs == null) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
@Override
@@ -57,7 +57,7 @@ public class AndroidTargetData {
final String attrsManifestPath = myTarget.getPath(IAndroidTarget.MANIFEST_ATTRIBUTES);
final XmlFile[] files = findXmlFiles(project, attrsPath, attrsManifestPath);
if (files != null) {
myAttrDefs = new AttributeDefinitions(files);
myAttrDefs = new AttributeDefinitionsImpl(files);
}
}
});
@@ -68,7 +68,7 @@ public class AndroidTargetData {
@Nullable
public RenderServiceFactory getRenderServiceFactory(@NotNull Project project) throws RenderingException, IOException {
if (myRenderServiceFactory == null) {
final AttributeDefinitions attrDefs = getAttrDefs(project);
final AttributeDefinitionsImpl attrDefs = getAttrDefs(project);
if (attrDefs == null) {
return null;
}
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:frameDur<caret>/>
android:visib<caret>/>
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:frameDuration=""/>
android:visible=""/>
@@ -3,6 +3,4 @@
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="<error>@drawable/adsdsd</error>"
android:pivotX="50%"
android:pivotY="50%"
android:framesCount="12"
android:frameDuration="<error>aba</error>"/>
android:pivotY="50%"/>
@@ -0,0 +1,5 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStar<caret>>
</LinearLayout>
@@ -0,0 +1,5 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStar>
</LinearLayout>
@@ -0,0 +1,5 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<warning>android:paddingStart</warning>="">
</LinearLayout>
@@ -663,6 +663,14 @@ public class AndroidLayoutDomTest extends AndroidDomTest {
doTestHighlighting();
}
public void testPrivateAttributesCompletion() throws Throwable {
doTestCompletion();
}
public void testPrivateAttributesHighlighting() throws Throwable {
doTestHighlighting();
}
public void testAttrReferences1() throws Throwable {
copyFileToProject("attrReferences_attrs.xml", "res/values/attrReferences_attrs.xml");
doTestHighlighting();