Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Truffle] Start implementing Module#deprecate_constant
Browse files Browse the repository at this point in the history
Brandon Fish committed Sep 25, 2016

Verified

This commit was signed with the committer’s verified signature. The key has expired.
nomadium Miguel Landaeta
1 parent daa6c8d commit b06f580
Showing 7 changed files with 89 additions and 6 deletions.
3 changes: 0 additions & 3 deletions spec/truffle/tags/core/module/deprecate_constant_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
fails:Module#deprecate_constant accepts multiple symbols and strings as constant names
fails:Module#deprecate_constant returns self
fails:Module#deprecate_constant raises a NameError when given an undefined name
fails:Module#deprecate_constant when accessing the deprecated module passes the accessing
fails:Module#deprecate_constant when accessing the deprecated module warns with a message
Original file line number Diff line number Diff line change
@@ -312,7 +312,8 @@ public void setConstantInternal(RubyContext context, Node currentNode, String na
while (true) {
final RubyConstant previous = constants.get(name);
final boolean isPrivate = previous != null && previous.isPrivate();
final RubyConstant newValue = new RubyConstant(rubyModuleObject, value, isPrivate, autoload);
final boolean isDeprecated = previous != null && previous.isDeprecated();
final RubyConstant newValue = new RubyConstant(rubyModuleObject, value, isPrivate, autoload, isDeprecated);

if ((previous == null) ? (constants.putIfAbsent(name, newValue) == null) : constants.replace(name, previous, newValue)) {
newLexicalVersion();
@@ -453,6 +454,26 @@ public void changeConstantVisibility(
}
}

@TruffleBoundary
public void deprecateConstant(
final RubyContext context,
final Node currentNode,
final String name) {

while (true) {
final RubyConstant previous = constants.get(name);

if (previous == null) {
throw new RaiseException(context.getCoreExceptions().nameErrorUninitializedConstant(rubyModuleObject, name, currentNode));
}

if (constants.replace(name, previous, previous.withDeprecated())) {
newLexicalVersion();
break;
}
}
}

public RubyContext getContext() {
return context;
}
Original file line number Diff line number Diff line change
@@ -1629,6 +1629,29 @@ public DynamicObject privateConstant(VirtualFrame frame, DynamicObject module, O
}
}

@CoreMethod(names = "deprecate_constant", rest = true)
public abstract static class DeprecateConstantNode extends CoreMethodArrayArgumentsNode {

@Child NameToJavaStringNode nameToJavaStringNode = NameToJavaStringNode.create();
@Child IsFrozenNode isFrozenNode;

public DeprecateConstantNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
this.nameToJavaStringNode = NameToJavaStringNode.create();
this.isFrozenNode = IsFrozenNodeGen.create(context, sourceSection, null);
}

@Specialization
public DynamicObject deprecateConstant(VirtualFrame frame, DynamicObject module, Object[] args) {
isFrozenNode.raiseIfFrozen(module);
for (Object arg : args) {
String name = nameToJavaStringNode.executeToJavaString(frame, arg);
Layouts.MODULE.getFields(module).deprecateConstant(getContext(), this, name);
}
return module;
}
}

@CoreMethod(names = "public_constant", rest = true)
public abstract static class PublicConstantNode extends CoreMethodArrayArgumentsNode {

18 changes: 16 additions & 2 deletions truffle/src/main/java/org/jruby/truffle/language/RubyConstant.java
Original file line number Diff line number Diff line change
@@ -20,13 +20,15 @@ public class RubyConstant {
private final Object value;
private final boolean isPrivate;
private final boolean autoload;
private final boolean isDeprecated;

public RubyConstant(DynamicObject declaringModule, Object value, boolean isPrivate, boolean autoload) {
public RubyConstant(DynamicObject declaringModule, Object value, boolean isPrivate, boolean autoload, boolean isDeprecated) {
assert RubyGuards.isRubyModule(declaringModule);
this.declaringModule = declaringModule;
this.value = value;
this.isPrivate = isPrivate;
this.autoload = autoload;
this.isDeprecated = isDeprecated;
}

public DynamicObject getDeclaringModule() {
@@ -41,11 +43,23 @@ public boolean isPrivate() {
return isPrivate;
}

public boolean isDeprecated() {
return isDeprecated;
}

public RubyConstant withPrivate(boolean isPrivate) {
if (isPrivate == this.isPrivate) {
return this;
} else {
return new RubyConstant(declaringModule, value, isPrivate, autoload);
return new RubyConstant(declaringModule, value, isPrivate, autoload, isDeprecated);
}
}

public RubyConstant withDeprecated() {
if (this.isDeprecated()) {
return this;
} else {
return new RubyConstant(declaringModule, value, isPrivate, autoload, true);
}
}

Original file line number Diff line number Diff line change
@@ -74,9 +74,17 @@ protected RubyConstant lookupConstant(
if (!isVisible) {
throw new RaiseException(coreExceptions().nameErrorPrivateConstant(module, name, this));
}
if(constant != null && constant.isDeprecated()){
warnDeprecatedConstant(name);
}
return constant;
}

@TruffleBoundary
private void warnDeprecatedConstant(String name) {
getContext().getJRubyRuntime().getWarnings().warn("constant " + name + " is deprecated");
}

public Assumption getUnmodifiedAssumption(DynamicObject module) {
return Layouts.MODULE.getFields(module).getUnmodifiedAssumption();
}
@@ -90,6 +98,9 @@ protected RubyConstant lookupConstantUncached(DynamicObject module, String name)
if (!isVisible) {
throw new RaiseException(coreExceptions().nameErrorPrivateConstant(module, name, this));
}
if(constant != null && constant.isDeprecated()){
warnDeprecatedConstant(name);
}
return constant;
}

Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
package org.jruby.truffle.language.constants;

import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
@@ -49,6 +50,9 @@ protected RubyConstant lookupConstant(VirtualFrame frame,
if (!isVisible) {
throw new RaiseException(coreExceptions().nameErrorPrivateConstant(getModule(), name, this));
}
if(constant != null && constant.isDeprecated()){
warnDeprecatedConstant(name);
}
return constant;
}

@@ -64,4 +68,9 @@ protected boolean isVisible(RubyConstant constant) {
return constant == null || constant.isVisibleTo(getContext(), lexicalScope, getModule());
}

@TruffleBoundary
private void warnDeprecatedConstant(String name) {
getContext().getJRubyRuntime().getWarnings().warn("constant " + name + " is deprecated");
}

}
Original file line number Diff line number Diff line change
@@ -74,6 +74,9 @@ private RubyConstant deepConstantSearch(String name, DynamicObject lexicalParent
if (constant != null && !constant.isVisibleTo(getContext(), LexicalScope.NONE, lexicalParent)) {
throw new RaiseException(getContext().getCoreExceptions().nameErrorPrivateConstant(lexicalParent, name, this));
}
if(constant != null && constant.isDeprecated()){
warnDeprecatedConstant(name);
}
return constant;
}

@@ -85,4 +88,9 @@ public RequireNode getRequireNode() {
return requireNode;
}

@TruffleBoundary
private void warnDeprecatedConstant(String name) {
getContext().getJRubyRuntime().getWarnings().warn("constant " + name + " is deprecated");
}

}

0 comments on commit b06f580

Please sign in to comment.