001/*
002 * Copyright (c) 2012-2017 Institut National des Sciences Appliquées de Lyon (INSA-Lyon)
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 */
009
010package org.eclipse.golo.compiler.ir;
011
012import org.eclipse.golo.compiler.parser.GoloASTNode;
013
014public final class LocalReference extends GoloElement {
015
016  public static enum Kind {
017    CONSTANT, VARIABLE, MODULE_CONSTANT, MODULE_VARIABLE
018  }
019
020  private Kind kind = Kind.CONSTANT;
021  private final String name;
022  private boolean synthetic = false;
023  private int index = -1;
024
025  LocalReference(String name) {
026    super();
027    this.name = name;
028  }
029
030  @Override
031  public LocalReference ofAST(GoloASTNode n) {
032    super.ofAST(n);
033    return this;
034  }
035
036  public Kind getKind() {
037    return kind;
038  }
039
040  public LocalReference variable() {
041    if (kind == Kind.MODULE_VARIABLE || kind == Kind.MODULE_CONSTANT) {
042      kind = Kind.MODULE_VARIABLE;
043    } else {
044      kind = Kind.VARIABLE;
045    }
046    return this;
047  }
048
049  public LocalReference moduleLevel() {
050    if (kind == Kind.CONSTANT || kind == Kind.MODULE_CONSTANT) {
051      kind = Kind.MODULE_CONSTANT;
052    } else {
053      kind = Kind.MODULE_VARIABLE;
054    }
055    return this;
056  }
057
058  public LocalReference kind(Kind k) {
059    kind = k;
060    return this;
061  }
062
063  public String getName() {
064    return name;
065  }
066
067  public LocalReference synthetic(boolean isSynthetic) {
068    this.synthetic = isSynthetic;
069    return this;
070  }
071
072  public LocalReference synthetic() {
073    return synthetic(true);
074  }
075
076  public boolean isSynthetic() {
077    return synthetic;
078  }
079
080  public boolean isModuleState() {
081    return kind == Kind.MODULE_CONSTANT || kind == Kind.MODULE_VARIABLE;
082  }
083
084  public boolean isConstant() {
085    return kind == Kind.CONSTANT || kind == Kind.MODULE_CONSTANT;
086  }
087
088  public int getIndex() {
089    return index;
090  }
091
092  public void setIndex(int index) {
093    this.index = index;
094  }
095
096  public LocalReference index(int index) {
097    setIndex(index);
098    return this;
099  }
100
101  public ReferenceLookup lookup() {
102    return new ReferenceLookup(name);
103  }
104
105  @Override
106  public String toString() {
107    return String.format("LocalReference{kind=%s, name='%s', index=%d}", kind, name, index);
108  }
109
110  @Override
111  public boolean equals(Object o) {
112    if (this == o) { return true; }
113    if (o == null || getClass() != o.getClass()) { return false; }
114    LocalReference that = (LocalReference) o;
115    return kind == that.kind && name.equals(that.name);
116  }
117
118  @Override
119  public int hashCode() {
120    int result = kind.hashCode();
121    result = 31 * result + name.hashCode();
122    return result;
123  }
124
125  @Override
126  public void accept(GoloIrVisitor visitor) {
127    visitor.visitLocalReference(this);
128  }
129
130  @Override
131  public void walk(GoloIrVisitor visitor) {
132    // nothing to do, not a composite
133  }
134
135  @Override
136  protected void replaceElement(GoloElement original, GoloElement newElement) {
137    throw cantReplace();
138  }
139}