package slangc.model; import slang.data.List; import slangc.parser.Branch; import slangc.parser.ErrorType; import slangc.parser.Language; import slangc.parser.Node; import slangc.parser.NodeType; import slangc.parser.Token; public class AttributeSet { private AttributeOwner owner; private Branch source; private boolean isStatic = false; private boolean isPublic = false; private boolean isPrivate = false; private boolean isProtected = false; private boolean isAbstract = false; private boolean isFinal = false; private boolean isNative = false; private boolean isTransient = false; private boolean isSynchronized = false; private boolean isVolatile = false; private List translations = new List(); public static class Translation { public final String language; public final String name; public Translation(String language, String name) { this.language = language; this.name = name; } public boolean matches(String[] enabledLanguages, String name) { return matchesEnabledLanguages(enabledLanguages) && matchesName(name); } public boolean matchesEnabledLanguages(String[] enabledLanguages) { if (enabledLanguages == null) { return true; } else { for (int i = 0; i < enabledLanguages.length; i++) { if (enabledLanguages[i].equals(language)) { return true; } } return false; } } public boolean matchesName(String n) { return n.equals(this.name); } } public int countTranslations() { return translations.count(); } public Translation getTranslation(int i) { return translations.get(i); } public int getFlags() { int f = 0; if (isPublic()) { f |= Flags.MASK_PUBLIC; } else if (isPrivate()) { f |= Flags.MASK_PRIVATE; } else if (isProtected()) { f |= Flags.MASK_PROTECTED; } else { f |= Flags.MASK_PACKAGE; } if (isStatic()) { f |= Flags.MASK_STATIC; } if (isAbstract()) { f |= Flags.MASK_PUBLIC; } if (isFinal()) { f |= Flags.MASK_FINAL; } if (isNative()) { f |= Flags.MASK_NATIVE; } if (isPublic()) { f |= Flags.MASK_TRANSIENT; } if (isPublic()) { f |= Flags.MASK_VOLATILE; } return f; } public AttributeSet(AttributeOwner owner, Branch source) { this.owner = owner; this.source = source; if (source != null) { for (int i = 0; i < source.countSubnodes(); i++) { Node n = source.getSubnode(i); if (n.getNodeType() == NodeType.SIMPLE_MODIFIER) { applySimpleModifier((Token)((Branch)n).getSubnode(0)); } else if (n.getNodeType() == NodeType.NAME_TAGGED_MODIFIER) { Node langName = ((Branch)n).getSubnode(1); Node itemName = ((Branch)n).getSubnode(3); Token lt = ((Token)((Branch) langName).getSubnode(0)); Token it = ((Token)((Branch) itemName).getSubnode(0)); applyTranslation(lt.getSnippet().getSource(), it.getSnippet().getSource()); } else if (n.getNodeType() == NodeType.SIMPLE_MODIFIER) { Node itemName = ((Branch)n).getSubnode(1); Token it = ((Token)((Branch) itemName).getSubnode(0)); applyTranslation("", it.getSnippet().getSource()); } } } } public void applyTranslation(String language, String name) { this.translations.append(new Translation(language, name)); } public boolean matchesTranslation(String[] enabledLanguages, String name) { for (int i = 0; i < translations.count(); i++) { Translation t = translations.get(i); if (t.matches(enabledLanguages, name)) { return true; } } return false; } public void applySimpleModifier(Token name) { String src = name.getSnippet().getSource(); if (name.getOwner().getLanguage().matches(Language.Key.PUBLIC, src)) { if (isPublic) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); } else if (isPrivate || isProtected) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); } isPublic = true; return; } if (name.getOwner().getLanguage().matches(Language.Key.STATIC, src)) { //src.equals("static")) { if (isStatic) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); }/* else if (isAbstract) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); }*/ isStatic = true; } else if (name.getOwner().getLanguage().matches(Language.Key.ABSTRACT, src)) { //src.equals("abstract")) { if (isAbstract) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); } else if (isFinal || isNative) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); } isAbstract = true; } else if (name.getOwner().getLanguage().matches(Language.Key.FINAL, src)) { //src.equals("final")) { if (isFinal) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); } else if (isAbstract) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); } isFinal = true; } else if (name.getOwner().getLanguage().matches(Language.Key.NATIVE, src)) { //src.equals("native")) { if (isNative) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); }/* else if (isStatic || isAbstract) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); }*/ isNative = true; } else if (name.getOwner().getLanguage().matches(Language.Key.PUBLIC, src)) { //src.equals("public")) { // default setting left } else if (name.getOwner().getLanguage().matches(Language.Key.PRIVATE, src)) { //src.equals("private")) { if (isPrivate) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); } else if (isPublic || isProtected) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); } isPrivate = true; } else if (name.getOwner().getLanguage().matches(Language.Key.PROTECTED, src)) {//src.equals("protected")) { if (isProtected) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); } else if (isPublic || isPrivate) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); } isProtected = true; } else if (name.getOwner().getLanguage().matches(Language.Key.TRANSIENT, src)) { //src.equals("transient")) { if (isTransient) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); }/* else if (isPublic) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); }*/ isTransient = true; } else if (name.getOwner().getLanguage().matches(Language.Key.SYNCHRONISED, src)) { //src.equals("synchronized")) { if (isSynchronized) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); }/* else if (isPublic) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); }*/ isSynchronized = true; } else if (name.getOwner().getLanguage().matches(Language.Key.VOLATILE, src)) { //src.equals("volatile")) { if (isVolatile) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier is already set"); }/* else if (isPublic) { name.annotate(ErrorType.INTERNAL_ERROR, "This modifier conflicts with another modifier"); }*/ isVolatile = true; } else { name.annotate(ErrorType.INTERNAL_ERROR, "Unrecognised modifier"); } } public AttributeOwner getOwner() { return owner; } public Branch getSource() { return source; } public boolean isStatic() { return isStatic; } public boolean isAbstract() { return isAbstract; } public boolean isFinal() { return isFinal; } public boolean isNative() { return isNative; } public boolean isPrivate() { return isPrivate; } public boolean isPublic() { return isPublic; } public boolean isProtected() { return isProtected; } public boolean isTransient() { return isTransient; } public boolean isSynchronized() { return isSynchronized; } public boolean isVolatile() { return isVolatile; } }