profile
viewpoint
Alex Hoppen ahoppen CS Student @ RWTH Aachen Cologne https://alexhoppen.de CS Student @ RWTH Aachen University | Swift compiler committer | Former DevTools intern @ Apple | License on Blockchain

ahoppen/introduction-to-compilers 369

Swift Playground giving an overview over the inner workings of modern compilers

ahoppen/colour-clustering-playground 11

My WWDC 2019 scholarship application

ahoppen/swift 1

The Swift Programming Language

ahoppen/2016 0

Student Submissions for the WWDC 2016 Scholarship

ahoppen/ath10k-ct 0

Stand-alone ath10k driver based on Candela Technologies Linux kernel.

ahoppen/DataTables 0

Tables plug-in for jQuery

ahoppen/DynamicGrid 0

Drag and drop GridView for Android

ahoppen/forge 0

A native implementation of TLS in Javascript and tools to write crypto-based and network-heavy webapps

pull request commentapple/swift-syntax

Implement Additional Feedback on PR for SR-11580

On second thought, I quite agree with @xwu and @akyrtzi that we shouldn’t rely on semantic functionality. AFAICT it should be sufficient if we make the properties optional and remove the must_uphold_invariant thing as outlined above.

I’m sorry for all the work you have put into this, @vermont42, only so it needs to be scrapped now…

vermont42

comment created time in a month

PullRequestReviewEvent

pull request commentapple/swift-syntax

Add Double and Int Convenience Properties

@vermont42 What you need to do, is to rebase your swift PR so that the version in your branch contains both the concurrency changes as well as your changes and then re-generate the files for this PR. If you look at the diff for the generated files in this PR they should contain no concurrency-related changes.

vermont42

comment created time in a month

pull request commentapple/swift-syntax

Add Double and Int Convenience Properties

Ah, I see. Let me know when you have regenerated the files and I will trigger CI again.

vermont42

comment created time in a month

pull request commentapple/swift-syntax

Add Double and Int Convenience Properties

https://github.com/apple/swift/pull/33948

@swift-ci Please test

vermont42

comment created time in a month

pull request commentapple/swift-syntax

Add Double and Int Convenience Properties

https://github.com/apple/swift/pull/33948

@swift-ci Please test

@vermont42 Could you squash the commits again?

vermont42

comment created time in a month

pull request commentapple/swift-syntax

Add Double and Int Convenience Properties

https://github.com/apple/swift/pull/33948

@swift-ci Please test

vermont42

comment created time in a month

pull request commentapple/swift-syntax

Add Double and Int Convenience Properties

@ahoppen I squashed all but my first commit, which I reworded to Implements SR-11580. I'm not sure why Doug's commit appears in my commit history because I left that as pick.

I think Doug’s commit should disappear if you rebase your PR on the current master branch. That way you should also be able to remove the merge commit.

vermont42

comment created time in a month

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 public class SyntaxTests: XCTestCase {     XCTAssertEqual(Syntax(integerExpr), Syntax(fromProtocol: integerExpr as SyntaxProtocol))     XCTAssertEqual(Syntax(integerExpr), Syntax(fromProtocol: integerExpr as ExprSyntaxProtocol))   }++  public func testNumericLiteralSetters() {+    var integerExpr = IntegerLiteralExprSyntax {+      $0.useDigits(SyntaxFactory.makeIntegerLiteral("1"))+    }!+    XCTAssert(integerExpr.isValid)++    var token: TokenSyntax+    var source = "2"+    var tree = try! SyntaxParser.parse(source: source)+    token = tree.firstToken!+    try! integerExpr.setDigits(token)+    XCTAssert(integerExpr.isValid)++    let invalidNumericLiteral = "🥥"++    source = invalidNumericLiteral+    tree = try! SyntaxParser.parse(source: source)+    token = tree.firstToken!+    do {+      try integerExpr.setDigits(token)

I think there’s XCTAssertThrowsError to test that an error is thrown. This test would also pass if setDigits doesn’t throw.

vermont42

comment created time in a month

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 public struct ${node.name}: ${base_type}Protocol, SyntaxHashable { %       end       return ${child.type_name}(childData!)     }+%       if not node.must_uphold_invariant:     set(value) {-%       if node.must_uphold_invariant:-      self = with${child.name}(value)!-%       else:       self = with${child.name}(value)+    } %       end+  }+%       if node.must_uphold_invariant:++  public enum ${child.name}Error: Error, CustomStringConvertible {+    case invalid(${child.swift_name}: ${ret_type})++    public var description: String {+      switch self {+      case .invalid(let ${child.swift_name}):+        return "attempted to use setter with invalid ${child.name} \"\(${child.swift_name})\""+      }+    }+  }++  mutating public func set${child.name}(_ ${child.swift_name}: ${ret_type}) throws {+    if let tokenSyntax = with${child.name}(${child.swift_name}) {

I think technically this variable shouldn’t be called tokenSyntax because the child doesn’t need to be a token (although it is in both of our cases). I would prefer something like childSyntax or something along those lines.

vermont42

comment created time in a month

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 public class SyntaxTests: XCTestCase {     XCTAssertEqual(Syntax(integerExpr), Syntax(fromProtocol: integerExpr as SyntaxProtocol))     XCTAssertEqual(Syntax(integerExpr), Syntax(fromProtocol: integerExpr as ExprSyntaxProtocol))   }++  public func testNumericLiteralSetters() {+    var integerExpr = IntegerLiteralExprSyntax {+      $0.useDigits(SyntaxFactory.makeIntegerLiteral("1"))+    }!+    XCTAssert(integerExpr.isValid)++    var token: TokenSyntax+    var source = "2"+    var tree = try! SyntaxParser.parse(source: source)+    token = tree.firstToken!+    try! integerExpr.setDigits(token)+    XCTAssert(integerExpr.isValid)++    let invalidNumericLiteral = "🥥"++    source = invalidNumericLiteral+    tree = try! SyntaxParser.parse(source: source)+    token = tree.firstToken!+    do {+      try integerExpr.setDigits(token)+    } catch {+      if let error = error as? IntegerLiteralExprSyntax.DigitsError {+        XCTAssertEqual("attempted to use setter with invalid Digits \"\(source)\"", error.description)+      } else {+        XCTFail("unexpected error thrown")+      }+    }++    var floatExpr = FloatLiteralExprSyntax {+      $0.useFloatingDigits(SyntaxFactory.makeFloatingLiteral("4.2"))+    }!+    XCTAssert(floatExpr.isValid)++    source = "2.4"+    tree = try! SyntaxParser.parse(source: source)+    token = tree.firstToken!+    try! floatExpr.setFloatingDigits(token)+    XCTAssert(floatExpr.isValid)++    source = invalidNumericLiteral+    tree = try! SyntaxParser.parse(source: source)+    token = tree.firstToken!+    do {+      try floatExpr.setFloatingDigits(token)

Same here. Use XCTAssertThrowsError.

vermont42

comment created time in a month

PullRequestReviewEvent
PullRequestReviewEvent

issue commentgreearb/ath10k-ct

Unable to compile ath10k-ct for OpenWrt

Thanks for the reply! For anyone hitting this, I managed to get ath10k-ct building by pointing the OpenWrt build to a different commit hash of ath10k-ct.

ahoppen

comment created time in a month

create barnchahoppen/ath10k-ct

branch : cherry-pick-vlans

created branch time in a month

fork ahoppen/ath10k-ct

Stand-alone ath10k driver based on Candela Technologies Linux kernel.

fork in a month

issue openedgreearb/ath10k-ct

Unable to compile ath10k-ct for OpenWrt

I am trying to compile a recent-ish version of ath10k-ct for OpenWrt 19.07 in order to backport https://github.com/greearb/ath10k-ct/pull/119 to 19.07 so I can use dynamic VLANs on TP-Link Archer C7 v5 devices (please correct me if my assumption that this should work is wrong).

For this I have compiled OpenWrt 19.07.2 and am now trying to compile the master version of ath10k-ct. However, AFAICT nothing is being built (at least the build command finishes in < 1 second and I can’t find any output files).

Could someone give me a hint what I might be doing wrong? I assume it’s something fairly trivial but I’m unable to find it.

$ ./build_me.sh 
Enter your kernel's build directory:
/home/alex/openwrt/build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.14.171
Enter kernel version to build for: 4.4, 4.7, 4.9, 4.13  (or enter for default which is 4.7 currently):
4.13
 * These flags are used with the ampdu_action() callback in
	 * @ampdu_action:
	int (*ampdu_action)(struct ieee80211_hw *hw,
 * @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without
	RX_FLAG_ONLY_MONITOR		= BIT(17),
Running tmp/ath10k.build/build_me.sh
make: Entering directory '/home/alex/openwrt/build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.14.171'
  Building modules, stage 2.
  MODPOST 0 modules
make: Leaving directory '/home/alex/openwrt/build_dir/target-mips_24kc_musl/linux-ar71xx_generic/linux-4.14.171'

created time in a month

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 public enum SyntaxFactory {   } %   end -%   if not node.is_base():+%   if not node.is_base() and not node.must_uphold_invariant:

Ping @harlanhaskins

vermont42

comment created time in a month

PullRequestReviewEvent

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 open class SyntaxRewriter {       if let newNode = visitAny(node._syntaxNode) { return newNode }       return Syntax(visit(node)) %   else:+%     if node.must_uphold_invariant:+      let node = ${node.name}(data)!

I think you forgot to add the comment ;-)

vermont42

comment created time in a month

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {       return ${child.type_name}(childData!)     }     set(value) {+%       if node.must_uphold_invariant:+      self = with${child.name}(value)!

I just realised that this will crash when setting the digits of an integer literal to an invalid integer literal. This is definitely not ideal. I see four options on how to resolve this. a) Maintain the crashing behaviour and add a comment to the setter that at least explains the crash b) Remove the property setter on all types and add a set${child.name} method that throws if the invariant is not satisfied c) Only replace the property setter by a function on types that have an invariant d) Remove the setter altogether and only use the with${child.name} to modify types

From my point of view a) leads to surprising crashes for the user so I don’t prefer it b) offers a consistent API across all types that is safe but does not follow standard Swift conventions c) maintains standard Swift conventions for most types but maybe makes the throwing setters less discoverable because the API is no longer consistent between Syntax types d) removes a IMHO useful setter

I don’t have strong feelings between b) and c). @vermont42 What do you think is better?

Also: If you change the API, could you document it in Changelog.md and add a test that setting an invalid token as the text of an integer literal behaves correctly?

@akyrtzi: Do you have an opinion on this?

vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

+//===- SyntaxConvenienceMethods.swift - Convenience funcs for syntax nodes ===//+//+// This source file is part of the Swift.org open source project+//+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors+// Licensed under Apache License v2.0 with Runtime Library Exception+//+// See https://swift.org/LICENSE.txt for license information+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors+//+//===----------------------------------------------------------------------===//++public extension FloatLiteralExprSyntax {+  var floatingValue: Double {+    return potentialFloatingValue!+  }++  fileprivate var potentialFloatingValue: Double? {+    let floatingDigitsWithoutUnderscores = floatingDigits.text.filter {+      $0 != "_"+    }+    return Double(floatingDigitsWithoutUnderscores)+  }+}++public extension IntegerLiteralExprSyntax {+  var integerValue: Int {+    return potentialIntegerValue!+  }++  fileprivate var potentialIntegerValue: Int? {+    let text = digits.text+    let (prefixLength, radix) = IntegerLiteralExprSyntax.prefixLengthAndRadix(text: text)+    let digitsStartIndex = text.index(text.startIndex, offsetBy: prefixLength)+    let textWithoutPrefix = text.suffix(from: digitsStartIndex)++    let textWithoutPrefixOrUnderscores = textWithoutPrefix.filter {+      $0 != "_"+    }++    return Int(textWithoutPrefixOrUnderscores, radix: radix)+  }++  static func prefixLengthAndRadix(text: String) -> (Int, Int) {

Small nitpick after another round of review: I think this method should be private.

vermont42

comment created time in 2 months

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 open class SyntaxVisitor {       }       visitPost(node) %   else:+%     if node.must_uphold_invariant:+      let node = ${node.name}(data)!

Could you also add a comment like the one I suggested for SyntaxRewriter here?

vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {     let raw = newChild?.raw ?? ${make_missing_swift_child(child)} %       end     let newData = data.replacingChild(raw, at: Cursor.${child.swift_name})+%       if node.must_uphold_invariant:+    return ${node.name}(newData)!

We definitely shouldn‘t force unwrap here. The invariant will not be satisfied if the user passes in a child that does not satisfy the invariant (e.g. an invalid integer literal). Instead, this method should return an Optional.

vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 open class SyntaxRewriter {       if let newNode = visitAny(node._syntaxNode) { return newNode }       return Syntax(visit(node)) %   else:+%     if node.must_uphold_invariant:+      let node = ${node.name}(data)!

Could you add a comment like the following here to document why the use of the ! is safe here?

// We know that the SyntaxData is valid since we are walking a valid syntax tree and haven't modified the syntax data.  Thus the below initialiser will never return nil.
vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {   public init?(_ syntax: Syntax) {     guard syntax.raw.kind == .${node.swift_syntax_kind} else { return nil }     self._syntaxNode = syntax+%   if node.must_uphold_invariant:+    if !isValid {+      return nil+    }+%   end

I think it’s save to make it a fatalError if the node is not valid at this stage. By our invariant, we know that every Syntax node is valid and casting it should not change the invariant.

vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {   public init?(_ syntax: Syntax) {     guard syntax.raw.kind == .${node.swift_syntax_kind} else { return nil }     self._syntaxNode = syntax+%   if node.must_uphold_invariant:+    if !isValid {+      return nil+    }+%   end   }    /// Creates a `${node.name}` node from the given `SyntaxData`. This assumes   /// that the `SyntaxData` is of the correct kind. If it is not, the behaviour   /// is undefined.+%   if node.must_uphold_invariant:+  internal init?(_ data: SyntaxData) {+%   else:

Could you also update the comment to say that the initialiser returns nil if the invariant is not satisfied?

vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

 public enum SyntaxFactory {   } %   end -%   if not node.is_base():+%   if not node.is_base() and not node.must_uphold_invariant:

Technically, I don’t think it’s correct to remove the makeBlank method if a node must uphold an invariant.

In the future we might add invariants to other nodes as well that could have a valid blank content. One example that jumps to my mind would be string literals. For consistency, I would rather have this method return an Optional and return nil if the node kind has no valid blank representation.

@akyrtzi What do you think?

vermont42

comment created time in 2 months

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

+//===- SyntaxConvenienceMethods.swift - Convenience funcs for syntax nodes ===//+//+// This source file is part of the Swift.org open source project+//+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors+// Licensed under Apache License v2.0 with Runtime Library Exception+//+// See https://swift.org/LICENSE.txt for license information+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors+//+//===----------------------------------------------------------------------===//++public extension FloatLiteralExprSyntax {+  var floatingValue: Double {+    let floatingDigitsWithoutUnderscores = floatingDigits.text.filter {+      $0 != "_"+    }+    return Double(floatingDigitsWithoutUnderscores)!+  }+}++public extension IntegerLiteralExprSyntax {+  var integerValue: Int {+    let text = self.digits.text+    let type = IntegerType(text: text)+    let textWithoutPrefix: String+    let digitsStartIndex = text.index(text.startIndex, offsetBy: type.prefixLength())+    textWithoutPrefix = String(text.suffix(from: digitsStartIndex))++    let textWithoutPrefixOrUnderscores = textWithoutPrefix.filter {+      $0 != "_"

I would say that for now it’s sufficient if we uphold the invariant that the contents will of a integer / float literal are always parsable from the integerValue resp. floatingValue properties, especially since the implementation is nice and short so far!

That should already be an improvement over the current behaviour and if we add a FIXME, we can come back to it and improve it later.

vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

+import XCTest+import SwiftSyntax++public class SyntaxConvenienceMethodsTests: XCTestCase {++  public func testFloatingValues() {+    testFloatingValue(text: "5.3_8", expectedValue: 5.38)+    testFloatingValue(text: "12e3", expectedValue: 12000.0)+    testFloatingValue(text: "32E1", expectedValue: 320.0)+    testFloatingValue(text: "0xdEFACE.C0FFEEp+1", expectedValue: 29226397.507810354)+    testFloatingValue(text: "0xaffab1e.e1fP-2", expectedValue: 46131911.72064209)

The testing approach seems good to me. One idea though (I’m not quite sure if it’s an improvement or not) would be to use the literal that you’re specifying in the String also in the Swift source code, i.e.\

testFloatingValue(text: "0xaffab1e.e1fP-2", expectedValue: 0xaffab1e.e1fP-2)

Mostly because my mental hex parsing skills aren't brilliant and I’m not quite sure if 0xaffab1e.e1fP-2 is really equal to 46131911.72064209.

vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

+//===- SyntaxConvenienceMethods.swift - Convenience funcs for syntax nodes ===//+//+// This source file is part of the Swift.org open source project+//+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors+// Licensed under Apache License v2.0 with Runtime Library Exception+//+// See https://swift.org/LICENSE.txt for license information+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors+//+//===----------------------------------------------------------------------===//++public extension FloatLiteralExprSyntax {+  var floatingValue: Double {+    let floatingDigitsWithoutUnderscores = floatingDigits.text.filter {+      $0 != "_"+    }+    return Double(floatingDigitsWithoutUnderscores)!+  }+}++public extension IntegerLiteralExprSyntax {+  var integerValue: Int {+    let text = self.digits.text+    let (prefixLength, radix) = prefixLengthAndRadix(text: text)+    let digitsStartIndex = text.index(text.startIndex, offsetBy: prefixLength)+    let textWithoutPrefix = String(text.suffix(from: digitsStartIndex))++    let textWithoutPrefixOrUnderscores = textWithoutPrefix.filter {+      $0 != "_"+    }++    return Int(textWithoutPrefixOrUnderscores, radix: radix)!+  }++  private func prefixLengthAndRadix(text: String) -> (Int, Int) {+    let decimalPrefixLength = 0+    let nonDecimalPrefixLength = 2++    let binaryPrefix = "0b"+    let octalPrefix = "0o"+    let hexadecimalPrefix = "0x"++    let binaryRadix = 2+    let octalRadix = 8+    let decimalRadix = 10+    let hexadecimalRadix = 16++    switch String(text.prefix(nonDecimalPrefixLength)) {+    case binaryPrefix:+      return (nonDecimalPrefixLength, binaryRadix)

What about using binaryPrefix.count instead of the nonDecimalPrefixLength variable? Same below.

vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

+//===- SyntaxConvenienceMethods.swift - Convenience funcs for syntax nodes ===//+//+// This source file is part of the Swift.org open source project+//+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors+// Licensed under Apache License v2.0 with Runtime Library Exception+//+// See https://swift.org/LICENSE.txt for license information+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors+//+//===----------------------------------------------------------------------===//++public extension FloatLiteralExprSyntax {+  var floatingValue: Double {+    let floatingDigitsWithoutUnderscores = floatingDigits.text.filter {+      $0 != "_"+    }+    return Double(floatingDigitsWithoutUnderscores)!

I wouldn’t have thought that the Double initialiser can handle hex float literals.

I think it’s odd though, that the Double initialiser is able to handle hex literals while the Int initialiser is not. It’s not really part of this PR but it might be worth filing a bug report against the standard library to either support hex literals in both or neither of them.

vermont42

comment created time in 2 months

Pull request review commentapple/swift-syntax

Add Double and Int Convenience Properties

+//===- SyntaxConvenienceMethods.swift - Convenience funcs for syntax nodes ===//+//+// This source file is part of the Swift.org open source project+//+// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors+// Licensed under Apache License v2.0 with Runtime Library Exception+//+// See https://swift.org/LICENSE.txt for license information+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors+//+//===----------------------------------------------------------------------===//++public extension FloatLiteralExprSyntax {+  var floatingValue: Double {+    let floatingDigitsWithoutUnderscores = floatingDigits.text.filter {+      $0 != "_"+    }+    return Double(floatingDigitsWithoutUnderscores)!+  }+}++public extension IntegerLiteralExprSyntax {+  var integerValue: Int {+    let text = self.digits.text+    let (prefixLength, radix) = prefixLengthAndRadix(text: text)+    let digitsStartIndex = text.index(text.startIndex, offsetBy: prefixLength)+    let textWithoutPrefix = String(text.suffix(from: digitsStartIndex))

I don’t think you need the String initialiser wrapping text.suffix. It should be more efficient if the filter in the next line directly works on the Substring returned by suffix instead of copying the substring data to a new String buffer.

vermont42

comment created time in 2 months

pull request commentapple/swift-syntax

Add Double and Int Convenience Properties

However, if we do force-unwrap we need to protect against the tree getting into such state in the first place. I think we can safely assume that the parser will not provide such a node (and if it does that's a parser bug), but another source of these are the APIs for creating syntax nodes programmatically. It is important to catch invariant breakage at the earliest source, so we should prevent a case of manually creating a IntegerLiteralExprSyntax node with a string that is not an integer.

@akyrtzi I’ve just been digging around the generated code to give @vermont42 some advice on what needs to be modified. While doing so I have been thinking what the desired API would be. I would argue that making all methods that construct a integer/float literal return an Optional would be the cleanest solution, even though it means that these are the only types with a failable initialiser. What do you think?

vermont42

comment created time in 2 months

PublicEvent
more