wrap-cli icon indicating copy to clipboard operation
wrap-cli copied to clipboard

Allow reserved words to be used for AS class field names

Open krisbitney opened this issue 2 years ago • 14 comments

This PR allows reserved words to be used for both type property names and function argument names. Reserved words will no longer be prefixed with "m_". Instead, users will be expected to wrap reserved words in quotation marks.

Usage

schema.graphql

type Query {
  method1(
    const: Arg1!
  ): Result!
}

type Arg1 {
  const: String!
}

type Result {
  const: String!
}

index.ts

import {
  Input_method1,
  Result,
} from "./w3";

export function method1(input: Input_method1): Result {
  return {
    "const": "result: " + input.const.const,
  };
}

Closes issue #721

krisbitney avatar Mar 28 '22 20:03 krisbitney

Could you get tests to pass @krisbitney? We should make sure the AssemblyScript compiler doesn't complain about these keywords-as-type-properties by adding a few more tests for commonly used keywords: const, let, function, module, export, etc.

I'm good with this PR if we can prove that it indeed works with asc.

dOrgJelli avatar Mar 28 '22 22:03 dOrgJelli

Could you get tests to pass @krisbitney? We should make sure the AssemblyScript compiler doesn't complain about these keywords-as-type-properties by adding a few more tests for commonly used keywords: const, let, function, module, export, etc.

I'm good with this PR if we can prove that it indeed works with asc.

After looking at it, I think it should work but will require a change. It doesn't work with object literal syntax. Instead, we will need to add constructors to generated classes and use that syntax. I think users will still be able to use object literal syntax in cases where reserved words are not used for field names of the return value. What do you think? @dOrgJelli @Niraj-Kamdar

// doesn't compile
return {
 const: "foo"
};

// compiles
return new Result("foo");

krisbitney avatar Mar 29 '22 20:03 krisbitney

After looking into it further, I don't think it's possible to instantiate a class from an object literal when you declare a constructor. I thought it would be possible because I did some experimentation and I didn't get a compiler error, but it seems it doesn't work more generally.

I don't think this bug can be fixed. I think we need to accept the m_ prefix on class property names that are reserved words. The alternative is to lose object literal syntax altogether, which I think is a much greater inconvenience than the prefix.

krisbitney avatar Mar 29 '22 23:03 krisbitney

How about,

return {
"const": "foo",
}

Does this compile with asc?

Niraj-Kamdar avatar Mar 30 '22 15:03 Niraj-Kamdar

How about,

return {
"const": "foo",
}

Does this compile with asc?

that's a really good question. I'll find out.

krisbitney avatar Apr 03 '22 16:04 krisbitney

How about,

return {
"const": "foo",
}

Does this compile with asc?

Yes, this works. This PR will allow reserved words to be used for both property names and function arguments.

krisbitney avatar Apr 03 '22 21:04 krisbitney

Don't we still need to handleKeywords for module methods.

Ex:

type Query {
  type(token: String!): TokenType!
}

For above schema following as module file won't compile since type is a keyword.

export function type(token: string): TokenType {
  ...
}

This would work if we're using class for modules.

Sure thing. I'll add this feature for type and method names. This isn't something we had before. We were only allowing reserved words for property and argument names.

krisbitney avatar Apr 05 '22 16:04 krisbitney

After looking into this more, I think allowing reserved words to be used for type and method names is going to be a bit more complicated. Doing so will require changing the TypeInfo, since our Array and Map type definitions don't currently distinguish between object and non-object types.

For example, an Int32[] would contain items of type i32 in AssemblyScript. A naive implementation would prepend m_ to the type when generating the AssemblyScript code because "i32" is a reserved word.

I propose we handle type and method names in another issue and merge the fix for property and argument names.

krisbitney avatar Apr 12 '22 22:04 krisbitney

@krisbitney Can we get this merge and open issue for the fix for reserved words as a method name?

Niraj-Kamdar avatar May 06 '22 19:05 Niraj-Kamdar

After looking into this more, I think allowing reserved words to be used for type and method names is going to be a bit more complicated. Doing so will require changing the TypeInfo, since our Array and Map type definitions don't currently distinguish between object and non-object types.

For example, an Int32[] would contain items of type i32 in AssemblyScript. A naive implementation would prepend m_ to the type when generating the AssemblyScript code because "i32" is a reserved word.

Opened an issue here: https://github.com/polywrap/monorepo/issues/842

krisbitney avatar May 06 '22 19:05 krisbitney

I'm still a bit confused by this... why don't we just solve all naming cases (class, method, argument, property) by adding something like m_ in AssemblyScript? Ideally we should be able to handle these all in a similar way.

It's also worth noting that you can still use the reserved word when invoking the function with the PolywrapClient because it uses strings for method + argument names.

dOrgJelli avatar Jun 27 '22 22:06 dOrgJelli

I think this PR should address all cases in a unified way:

  • methods
  • arguments
  • type names

I propose the following: schema.graphql

type Module {
  const(float: Int32!): ArrayBuffer!
}

type ArrayBuffer {
  i32: Int32!
}

index.ts

import {
  Args__const,
  _ArrayBuffer
} from "./wrap";

export function _const(args: Args__const): string {
  const obj: _ArrayBuffer = {
    _i32: args._float
  };

  return obj;
}

This sounds good to me.

krisbitney avatar Jun 28 '22 07:06 krisbitney

I didn't like the appending reserved words with m_ but I really like the _ append approach.

But I have a question: Should users be allowed to create a _ prefixed field in the schema like: _foo?

Niraj-Kamdar avatar Jun 28 '22 08:06 Niraj-Kamdar

I didn't like the appending reserved words with m_ but I really like the _ append approach.

But I have a question: Should users be allowed to create a _ prefixed field in the schema like: _foo?

What if we prohibit the simultaneous existence of a reserved word and the same word with the _ prefix in the same namespace?

# const would be prefixed to _const in both the type and field names
type const {
  const: Int32!
}

# const would be prefixed to _const in just the type name
type const {
  _const: Int32!
}

# this would throw an exception and codegen would fail
type const {
  const: Int32!
  _const: Int32!
}

#  codegen would succeed because foo is not a reserved word
type bar {
  foo: Int32!
  _foo: Int32!
}

krisbitney avatar Jun 29 '22 17:06 krisbitney

replaced by https://github.com/polywrap/monorepo/pull/1171

krisbitney avatar Aug 22 '22 14:08 krisbitney